Merge "PG: autocomplete reviewers" into stable-2.16
diff --git a/rv-reviewers/rv-filter-section.html b/rv-reviewers/rv-filter-section.html
index d4784cc..104ecbd 100644
--- a/rv-reviewers/rv-filter-section.html
+++ b/rv-reviewers/rv-filter-section.html
@@ -77,6 +77,7 @@
<rv-reviewer
reviewer="{{item}}"
can-modify-config="[[canModifyConfig]]"
+ plugin-rest-api="[[pluginRestApi]]"
on-reviewer-deleted="_handleReviewerDeleted"
on-reviewer-added="_handleReviewerAdded">
</rv-reviewer>
diff --git a/rv-reviewers/rv-reviewer.html b/rv-reviewers/rv-reviewer.html
index 3609612..339eff7 100644
--- a/rv-reviewers/rv-reviewer.html
+++ b/rv-reviewers/rv-reviewer.html
@@ -19,24 +19,52 @@
<style include="shared-styles">
#editReviewerInput {
display: block;
+ width: 250px;
}
.reviewerRow {
align-items: center;
display: flex;
}
- #reviewerHeader, #editReviewerInput, #deleteCancelBtn, #addBtn {
+ #reviewerHeader,
+ #editReviewerInput,
+ #deleteCancelBtn,
+ #addBtn,
+ #reviewerField {
margin-left: 3px;
}
+ #reviewerField {
+ width: 250px;
+ text-indent: 1px;
+ border: 1px solid var(--border-color);
+ }
</style>
<style include="gr-form-styles"></style>
<div class="reviewerRow">
<h4 id="reviewerHeader">Reviewer:</h4>
- <input
- id="editReviewerInput"
- bind-value="{{reviewer}}"
- is="iron-input"
- type="text"
- disabled="[[_computeReviewerDisabled(reviewer, _originalReviewer)]]">
+ <template is="dom-if" if="[[_computeEditing(reviewer, _originalReviewer)]]">
+ <span class="value">
+ <!--
+ TODO:
+ Investigate wether we could reuse gr-account-list.
+ If the REST API returns AccountInfo instead of an account
+ identifier String we should be able to use gr-account-list(size=1)
+ for all reviewers, including those who are non-editable
+ (#reviewerField below) and allign the plugin with how accounts
+ are displayed in core Gerrit's UI.
+ -->
+ <gr-autocomplete
+ id="editReviewerInput"
+ text="{{reviewer}}"
+ value="{{_reviewerSearchId}}"
+ query="[[_queryReviewers]]"
+ placeholder="Name Or Email"
+ disabled="[[_computeReviewerDisabled(reviewer, _originalReviewer)]]">
+ </gr-autocomplete>
+ </span>
+ </template>
+ <template is="dom-if" if="[[!_computeEditing(reviewer, _originalReviewer)]]">
+ <td id="reviewerField">[[reviewer]]</td>
+ </template>
<gr-button
id="deleteCancelBtn"
on-tap="_handleDeleteCancel"
diff --git a/rv-reviewers/rv-reviewer.js b/rv-reviewers/rv-reviewer.js
index 9698a22..a8da113 100644
--- a/rv-reviewers/rv-reviewer.js
+++ b/rv-reviewers/rv-reviewer.js
@@ -16,8 +16,16 @@
is: 'rv-reviewer',
properties: {
- reviewer: String,
canModifyConfig: Boolean,
+ pluginRestAPi: Object,
+ reviewer: String,
+ _reviewerSearchId: String,
+ _queryReviewers: {
+ type: Function,
+ value() {
+ return this._getAccountSuggestions.bind(this);
+ },
+ },
_originalReviewer: String,
_deleted: Boolean,
_editing: {
@@ -48,13 +56,50 @@
_computeHideAddButton(reviewer, _originalReviewer) {
return !(this._computeEditing(reviewer, _originalReviewer)
- && this.$.editReviewerInput.value);
+ && this._reviewerSearchId);
},
_computeHideDeleteButton(canModifyConfig) {
return !canModifyConfig;
},
+ _getAccountSuggestions(input) {
+ if (input.length === 0) { return Promise.resolve([]); }
+ return this._getSuggestedAccounts(
+ input).then(accounts => {
+ const accountSuggestions = [];
+ let nameAndEmail;
+ let value;
+ if (!accounts) { return []; }
+ for (const key in accounts) {
+ if (!accounts.hasOwnProperty(key)) { continue; }
+ if (accounts[key].email) {
+ nameAndEmail = accounts[key].name +
+ ' <' + accounts[key].email + '>';
+ } else {
+ nameAndEmail = accounts[key].name;
+ }
+ if (accounts[key].username) {
+ value = accounts[key].username;
+ } else if (accounts[key].email) {
+ value = accounts[key].email;
+ } else {
+ value = accounts[key]._account_id;
+ }
+ accountSuggestions.push({
+ name: nameAndEmail,
+ value,
+ });
+ }
+ return accountSuggestions;
+ });
+ },
+
+ _getSuggestedAccounts(input) {
+ const suggestUrl = `/accounts/?suggest&q=${input}`;
+ return this.pluginRestApi.get(suggestUrl);
+ },
+
_handleDeleteCancel() {
const detail = {editing: this._editing};
if (this._editing) {
@@ -65,7 +110,7 @@
},
_handleAddReviewer() {
- const detail = {reviewer: this.reviewer};
+ const detail = {reviewer: this._reviewerSearchId};
this._originalReviewer = this.reviewer;
this.dispatchEvent(
new CustomEvent('reviewer-added', {detail, bubbles: true}));