| // 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'; |
| |
| // Maximum length for patch set descriptions. |
| const PATCH_DESC_MAX_LENGTH = 500; |
| |
| /** |
| * Fired when the patch range changes |
| * |
| * @event patch-range-change |
| * |
| * @property {string} leftPatch |
| * @property {string} rightPatch |
| */ |
| |
| Polymer({ |
| is: 'gr-patch-range-select', |
| |
| properties: { |
| availablePatches: Array, |
| changeNum: String, |
| comments: Array, |
| /** @type {{ meta_a: !Array, meta_b: !Array}} */ |
| filesWeblinks: Object, |
| /** @type {?} */ |
| patchRange: Object, |
| revisions: Object, |
| _sortedRevisions: Array, |
| _rightSelected: String, |
| _leftSelected: String, |
| }, |
| |
| observers: [ |
| '_updateSortedRevisions(revisions.*)', |
| '_updateSelected(patchRange.*)', |
| ], |
| |
| behaviors: [Gerrit.PatchSetBehavior], |
| |
| _updateSelected() { |
| this._rightSelected = this.patchRange.patchNum; |
| this._leftSelected = this.patchRange.basePatchNum; |
| }, |
| |
| _updateSortedRevisions(revisionsRecord) { |
| const revisions = revisionsRecord.base; |
| this._sortedRevisions = this.sortRevisions(Object.values(revisions)); |
| }, |
| |
| _handlePatchChange(e) { |
| const leftPatch = this._leftSelected; |
| const rightPatch = this._rightSelected; |
| this.fire('patch-range-change', {rightPatch, leftPatch}); |
| e.target.blur(); |
| }, |
| |
| _computeLeftDisabled(basePatchNum, patchNum, sortedRevisions) { |
| return this.findSortedIndex(basePatchNum, sortedRevisions) >= |
| this.findSortedIndex(patchNum, sortedRevisions); |
| }, |
| |
| _computeRightDisabled(patchNum, basePatchNum, sortedRevisions) { |
| if (basePatchNum == 'PARENT') { return false; } |
| |
| return this.findSortedIndex(patchNum, sortedRevisions) <= |
| this.findSortedIndex(basePatchNum, sortedRevisions); |
| }, |
| |
| // On page load, the dom-if for options getting added occurs after |
| // the value was set in the select. This ensures that after they |
| // are loaded, the correct value will get selected. I attempted to |
| // debounce these, but because they are detecting two different |
| // events, sometimes the timing was off and one ended up missing. |
| _synchronizeSelectionRight() { |
| this.$.rightPatchSelect.value = this._rightSelected; |
| }, |
| |
| _synchronizeSelectionLeft() { |
| this.$.leftPatchSelect.value = this._leftSelected; |
| }, |
| |
| // 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); |
| }); |
| }, |
| |
| // 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]; |
| }); |
| |
| return unresolvedLeaves.length; |
| }, |
| |
| _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 += ')'; |
| } |
| return commentsStr; |
| }, |
| |
| _computePatchSetDescription(revisions, patchNum) { |
| const rev = this.getRevisionByPatchNum(revisions, patchNum); |
| return (rev && rev.description) ? |
| rev.description.substring(0, PATCH_DESC_MAX_LENGTH) : ''; |
| }, |
| }); |
| })(); |