265 lines
8.1 KiB
JavaScript
265 lines
8.1 KiB
JavaScript
// 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';
|
|
|
|
// Maximum length for patch set descriptions.
|
|
const PATCH_DESC_MAX_LENGTH = 500;
|
|
|
|
Polymer({
|
|
is: 'gr-file-list-header',
|
|
|
|
properties: {
|
|
account: Object,
|
|
allPatchSets: Array,
|
|
change: Object,
|
|
changeNum: String,
|
|
changeUrl: String,
|
|
comments: Object,
|
|
commitInfo: Object,
|
|
editLoaded: Boolean,
|
|
loggedIn: Boolean,
|
|
serverConfig: Object,
|
|
shownFileCount: Number,
|
|
diffPrefs: Object,
|
|
diffViewMode: String,
|
|
/** @type {?} */
|
|
patchRange: {
|
|
type: Object,
|
|
observer: 'updateSelected',
|
|
},
|
|
revisions: Array,
|
|
// Caps the number of files that can be shown and have the 'show diffs' /
|
|
// 'hide diffs' buttons still be functional.
|
|
_maxFilesForBulkActions: {
|
|
type: Number,
|
|
readOnly: true,
|
|
value: 225,
|
|
},
|
|
_descriptionReadOnly: {
|
|
type: Boolean,
|
|
computed: '_computeDescriptionReadOnly(loggedIn, change, account)',
|
|
},
|
|
_selectedPatchSet: String,
|
|
_diffAgainst: String,
|
|
},
|
|
|
|
behaviors: [
|
|
Gerrit.PatchSetBehavior,
|
|
],
|
|
|
|
_expandAllDiffs() {
|
|
this.fire('expand-diffs');
|
|
},
|
|
|
|
_collapseAllDiffs() {
|
|
this.fire('collapse-diffs');
|
|
},
|
|
|
|
updateSelected() {
|
|
this._selectedPatchSet = this.patchRange.patchNum;
|
|
this._diffAgainst = this.patchRange.basePatchNum;
|
|
},
|
|
|
|
_computeDescriptionPlaceholder(readOnly) {
|
|
return (readOnly ? 'No' : 'Add a') + ' patch set description';
|
|
},
|
|
|
|
_computeDescriptionReadOnly(loggedIn, change, account) {
|
|
return !(loggedIn && (account._account_id === change.owner._account_id));
|
|
},
|
|
|
|
_computePatchSetDescription(change, patchNum) {
|
|
const rev = this.getRevisionByPatchNum(change.revisions, patchNum);
|
|
return (rev && rev.description) ?
|
|
rev.description.substring(0, PATCH_DESC_MAX_LENGTH) : '';
|
|
},
|
|
|
|
|
|
/**
|
|
* @param {!Object} revisions The revisions object keyed by revision hashes
|
|
* @param {?Object} patchSet A revision already fetched from {revisions}
|
|
* @return {string|undefined} the SHA hash corresponding to the revision.
|
|
*/
|
|
_getPatchsetHash(revisions, patchSet) {
|
|
for (const rev in revisions) {
|
|
if (revisions.hasOwnProperty(rev) &&
|
|
revisions[rev] === patchSet) {
|
|
return rev;
|
|
}
|
|
}
|
|
},
|
|
|
|
_handleDescriptionChanged(e) {
|
|
const desc = e.detail.trim();
|
|
const rev = this.getRevisionByPatchNum(this.change.revisions,
|
|
this._selectedPatchSet);
|
|
const sha = this._getPatchsetHash(this.change.revisions, rev);
|
|
this.$.restAPI.setDescription(this.changeNum,
|
|
this._selectedPatchSet, desc)
|
|
.then(res => {
|
|
if (res.ok) {
|
|
this.set(['_change', 'revisions', sha, 'description'], desc);
|
|
}
|
|
});
|
|
},
|
|
|
|
_computeBasePatchDisabled(patchNum, currentPatchNum) {
|
|
return this.findSortedIndex(patchNum, this.revisions) >=
|
|
this.findSortedIndex(currentPatchNum, this.revisions);
|
|
},
|
|
|
|
_computePrefsButtonHidden(prefs, loggedIn) {
|
|
return !loggedIn || !prefs;
|
|
},
|
|
|
|
// Copied from gr-file-list
|
|
_getCommentsForPath(comments, patchNum, path) {
|
|
return (comments[path] || []).filter(c => {
|
|
return this.patchNumEquals(c.patch_set, patchNum);
|
|
});
|
|
},
|
|
|
|
// Copied from gr-file-list
|
|
_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) {
|
|
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;
|
|
},
|
|
|
|
_fileListActionsVisible(shownFileCount, maxFilesForBulkActions) {
|
|
return shownFileCount <= maxFilesForBulkActions;
|
|
},
|
|
|
|
/**
|
|
* Determines if a patch number should be disabled based on value of the
|
|
* basePatchNum from gr-file-list.
|
|
* @param {number} patchNum Patch number available in dropdown
|
|
* @param {number|string} basePatchNum Base patch number from file list
|
|
* @return {boolean}
|
|
*/
|
|
_computePatchSetDisabled(patchNum, basePatchNum) {
|
|
if (basePatchNum === 'PARENT') { return false; }
|
|
|
|
return this.findSortedIndex(patchNum, this.revisions) <=
|
|
this.findSortedIndex(basePatchNum, this.revisions);
|
|
},
|
|
|
|
/**
|
|
* Change active patch to the provided patch num.
|
|
* @param {number|string} basePatchNum the base patch to be viewed.
|
|
* @param {number|string} patchNum the patch number to be viewed.
|
|
* @param {boolean} opt_forceParams When set to true, the resulting URL will
|
|
* always include the patch range, even if the requested patchNum is
|
|
* known to be the latest.
|
|
*/
|
|
_changePatchNum(patchNum, basePatchNum, opt_forceParams) {
|
|
if (!opt_forceParams) {
|
|
let currentPatchNum;
|
|
if (this.change.current_revision) {
|
|
currentPatchNum =
|
|
this.change.revisions[this.change.current_revision]._number;
|
|
} else {
|
|
currentPatchNum = this.computeLatestPatchNum(this.allPatchSets);
|
|
}
|
|
if (this.patchNumEquals(patchNum, currentPatchNum) &&
|
|
basePatchNum === 'PARENT') {
|
|
Gerrit.Nav.navigateToChange(this.change);
|
|
return;
|
|
}
|
|
}
|
|
Gerrit.Nav.navigateToChange(this.change, patchNum,
|
|
basePatchNum);
|
|
},
|
|
|
|
_handleBasePatchChange(e) {
|
|
this._changePatchNum(this._selectedPatchSet, e.target.value, true);
|
|
},
|
|
|
|
_handlePatchChange(e) {
|
|
this._changePatchNum(e.target.value, this._diffAgainst, true);
|
|
},
|
|
|
|
_handlePrefsTap(e) {
|
|
e.preventDefault();
|
|
this.fire('open-diff-prefs');
|
|
},
|
|
|
|
_handleDownloadTap(e) {
|
|
e.preventDefault();
|
|
this.fire('open-download-dialog');
|
|
},
|
|
|
|
_computeEditLoadedClass(editLoaded) {
|
|
return editLoaded ? 'editLoaded' : '';
|
|
},
|
|
|
|
_computePatchInfoClass(patchNum, allPatchSets) {
|
|
if (this.patchNumEquals(patchNum, this.EDIT_NAME)) {
|
|
return 'patchInfoEdit';
|
|
}
|
|
|
|
const latestNum = this.computeLatestPatchNum(allPatchSets);
|
|
if (this.patchNumEquals(patchNum, latestNum)) {
|
|
return '';
|
|
}
|
|
return 'patchInfoOldPatchSet';
|
|
},
|
|
});
|
|
})();
|