diff options
Diffstat (limited to 'polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js')
-rw-r--r-- | polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js | 244 |
1 files changed, 133 insertions, 111 deletions
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js index a8314e7618..cf8118f61b 100644 --- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js +++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.js @@ -1,16 +1,19 @@ -// Copyright (C) 2016 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. +/** + * @license + * Copyright (C) 2016 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'; @@ -34,26 +37,21 @@ _baseDropdownContent: { type: Object, computed: '_computeBaseDropdownContent(availablePatches, patchNum,' + - '_sortedRevisions, revisions, comments)', + '_sortedRevisions, changeComments, revisionInfo)', }, _patchDropdownContent: { type: Object, computed: '_computePatchDropdownContent(availablePatches,' + - 'basePatchNum, _sortedRevisions, revisions, comments)', + 'basePatchNum, _sortedRevisions, changeComments)', }, changeNum: String, - // In the case of a patch range select (like diff view) comments should - // be an empty array, so that the patch and base content computed values - // get triggered. - comments: { - type: Object, - value: () => { return {}; }, - }, + changeComments: Object, /** @type {{ meta_a: !Array, meta_b: !Array}} */ filesWeblinks: Object, patchNum: String, basePatchNum: String, revisions: Object, + revisionInfo: Object, _sortedRevisions: Array, }, @@ -64,135 +62,150 @@ behaviors: [Gerrit.PatchSetBehavior], _computeBaseDropdownContent(availablePatches, patchNum, _sortedRevisions, - revisions, comments) { + changeComments, revisionInfo) { + const parentCounts = revisionInfo.getParentCountMap(); + const currentParentCount = parentCounts.hasOwnProperty(patchNum) ? + parentCounts[patchNum] : 1; + const maxParents = revisionInfo.getMaxParents(); + const isMerge = currentParentCount > 1; + const dropdownContent = []; - dropdownContent.push({ - text: 'Base', - value: 'PARENT', - }); for (const basePatch of availablePatches) { const basePatchNum = basePatch.num; - dropdownContent.push({ + const entry = this._createDropdownEntry(basePatchNum, 'Patchset ', + _sortedRevisions, changeComments); + dropdownContent.push(Object.assign({}, entry, { disabled: this._computeLeftDisabled( basePatch.num, patchNum, _sortedRevisions), - triggerText: `Patchset ${basePatchNum}`, - text: `Patchset ${basePatchNum}` + - this._computePatchSetCommentsString(this.comments, basePatchNum), - mobileText: this._computeMobileText(basePatchNum, comments, - revisions), - bottomText: `${this._computePatchSetDescription( - revisions, basePatchNum)}`, - value: basePatch.num, + })); + } + + dropdownContent.push({ + text: isMerge ? 'Auto Merge' : 'Base', + value: 'PARENT', + }); + + for (let idx = 0; isMerge && idx < maxParents; idx++) { + dropdownContent.push({ + disabled: idx >= currentParentCount, + triggerText: `Parent ${idx + 1}`, + text: `Parent ${idx + 1}`, + mobileText: `Parent ${idx + 1}`, + value: -(idx + 1), }); } + return dropdownContent; }, - _computeMobileText(patchNum, comments, revisions) { + _computeMobileText(patchNum, changeComments, revisions) { return `${patchNum}` + - `${this._computePatchSetCommentsString(this.comments, patchNum)}` + + `${this._computePatchSetCommentsString(changeComments, patchNum)}` + `${this._computePatchSetDescription(revisions, patchNum, true)}`; }, _computePatchDropdownContent(availablePatches, basePatchNum, - _sortedRevisions, revisions, comments) { + _sortedRevisions, changeComments) { const dropdownContent = []; for (const patch of availablePatches) { const patchNum = patch.num; - dropdownContent.push({ - disabled: this._computeRightDisabled(patchNum, basePatchNum, + const entry = this._createDropdownEntry( + patchNum, patchNum === 'edit' ? '' : 'Patchset ', _sortedRevisions, + changeComments); + dropdownContent.push(Object.assign({}, entry, { + disabled: this._computeRightDisabled(basePatchNum, patchNum, _sortedRevisions), - triggerText: `${patchNum === 'edit' ? '': 'Patchset '}` + - patchNum, - text: `${patchNum === 'edit' ? '': 'Patchset '}${patchNum}` + - `${this._computePatchSetCommentsString( - this.comments, patchNum)}`, - mobileText: this._computeMobileText(patchNum, comments, revisions), - bottomText: `${this._computePatchSetDescription( - revisions, patchNum)}`, - value: patchNum, - }); + })); } return dropdownContent; }, + _createDropdownEntry(patchNum, prefix, sortedRevisions, changeComments) { + const entry = { + triggerText: `${prefix}${patchNum}`, + text: `${prefix}${patchNum}` + + `${this._computePatchSetCommentsString( + changeComments, patchNum)}`, + mobileText: this._computeMobileText(patchNum, changeComments, + sortedRevisions), + bottomText: `${this._computePatchSetDescription( + sortedRevisions, patchNum)}`, + value: patchNum, + }; + const date = this._computePatchSetDate(sortedRevisions, patchNum); + if (date) { + entry['date'] = date; + } + return entry; + }, + _updateSortedRevisions(revisionsRecord) { const revisions = revisionsRecord.base; this._sortedRevisions = this.sortRevisions(Object.values(revisions)); }, + /** + * The basePatchNum should always be <= patchNum -- because sortedRevisions + * is sorted in reverse order (higher patchset nums first), invalid base + * patch nums have an index greater than the index of patchNum. + * @param {number|string} basePatchNum The possible base patch num. + * @param {number|string} patchNum The current selected patch num. + * @param {!Array} sortedRevisions + */ _computeLeftDisabled(basePatchNum, patchNum, sortedRevisions) { - return this.findSortedIndex(basePatchNum, sortedRevisions) >= + return this.findSortedIndex(basePatchNum, sortedRevisions) <= this.findSortedIndex(patchNum, sortedRevisions); }, - _computeRightDisabled(patchNum, basePatchNum, sortedRevisions) { - if (basePatchNum == 'PARENT') { return false; } + /** + * The basePatchNum should always be <= patchNum -- because sortedRevisions + * is sorted in reverse order (higher patchset nums first), invalid patch + * nums have an index greater than the index of basePatchNum. + * + * In addition, if the current basePatchNum is 'PARENT', all patchNums are + * valid. + * + * If the curent basePatchNum is a parent index, then only patches that have + * at least that many parents are valid. + * + * @param {number|string} basePatchNum The current selected base patch num. + * @param {number|string} patchNum The possible patch num. + * @param {!Array} sortedRevisions + * @return {boolean} + */ + _computeRightDisabled(basePatchNum, patchNum, sortedRevisions) { + if (this.patchNumEquals(basePatchNum, 'PARENT')) { return false; } - return this.findSortedIndex(patchNum, sortedRevisions) <= - this.findSortedIndex(basePatchNum, sortedRevisions); - }, + if (this.isMergeParent(basePatchNum)) { + // Note: parent indices use 1-offset. + return this.revisionInfo.getParentCount(patchNum) < + this.getParentIndex(basePatchNum); + } - // Copied from gr-file-list - // @todo(beckysiegel) clean up. - _getCommentsForPath(comments, patchNum, path) { - return (comments[path] || []).filter(c => { - return this.patchNumEquals(c.patch_set, patchNum); - }); + return this.findSortedIndex(basePatchNum, sortedRevisions) <= + this.findSortedIndex(patchNum, sortedRevisions); }, - // Copied from gr-file-list - // @todo(beckysiegel) clean up. - _computeUnresolvedNum(comments, drafts, patchNum, path) { - comments = this._getCommentsForPath(comments, patchNum, path); - drafts = this._getCommentsForPath(drafts, patchNum, path); - comments = comments.concat(drafts); - - // Create an object where every comment ID is the key of an unresolved - // comment. - - 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]; - }); + _computePatchSetCommentsString(changeComments, patchNum) { + if (!changeComments) { return; } - return unresolvedLeaves.length; - }, + const commentCount = changeComments.computeCommentCount(patchNum); + const commentString = GrCountStringFormatter.computePluralString( + commentCount, 'comment'); - _computePatchSetCommentsString(allComments, patchNum) { - // todo (beckysiegel) get comment strings for diff view also. - if (!allComments) { return ''; } - let numComments = 0; - let numUnresolved = 0; - for (const file in allComments) { - if (allComments.hasOwnProperty(file)) { - numComments += this._getCommentsForPath( - allComments, patchNum, file).length; - numUnresolved += this._computeUnresolvedNum( - allComments, {}, patchNum, file); - } - } - let commentsStr = ''; - if (numComments > 0) { - commentsStr = ' (' + numComments + ' comments'; - if (numUnresolved > 0) { - commentsStr += ', ' + numUnresolved + ' unresolved'; - } - commentsStr += ')'; + const unresolvedCount = changeComments.computeUnresolvedNum(patchNum); + const unresolvedString = GrCountStringFormatter.computeString( + unresolvedCount, 'unresolved'); + + if (!commentString.length && !unresolvedString.length) { + return ''; } - return commentsStr; + + return ` (${commentString}` + + // Add a comma + space if both comments and unresolved + (commentString && unresolvedString ? ', ' : '') + + `${unresolvedString})`; }, /** @@ -208,6 +221,15 @@ }, /** + * @param {!Array} revisions + * @param {number|string} patchNum + */ + _computePatchSetDate(revisions, patchNum) { + const rev = this.getRevisionByPatchNum(revisions, patchNum); + return rev ? rev.created : undefined; + }, + + /** * Catches value-change events from the patchset dropdowns and determines * whether or not a patch change event should be fired. */ |