Merge changes Id2d46f55,I820173fa,I2043efb1,Iebaa8387,Ife290c4c, ...
* changes:
Hide "Assignee" related components when disabled in config
Add a blurred attribute to account-label
Add attention icon to account components
Add reviewers column to dashboard
Add comments column to dashboard
Show reviewers next to each other
Use display name in account label
diff --git a/plugins/download-commands b/plugins/download-commands
index 47b783e..e26ed31 160000
--- a/plugins/download-commands
+++ b/plugins/download-commands
@@ -1 +1 @@
-Subproject commit 47b783ea75036664dd591d2d3f1bcd06b68cdd5e
+Subproject commit e26ed31aaf070ff884e96b9a09d39c20437de6cb
diff --git a/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior.js b/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior.js
index d12b279..0a3da6e 100644
--- a/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior.js
+++ b/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior.js
@@ -29,6 +29,8 @@
'Status',
'Owner',
'Assignee',
+ 'Reviewers',
+ 'Comments',
'Repo',
'Branch',
'Updated',
@@ -61,6 +63,35 @@
},
/**
+ * Is the column disabled by a server config or experiment? For example the
+ * assignee feature might be disabled and thus the corresponding column is
+ * also disabled.
+ *
+ * @param {string} column
+ * @param {Object} config
+ * @param {!Array<string>} experiments
+ * @return {boolean}
+ */
+ isColumnEnabled(column, config, experiments) {
+ if (!config || !config.change) return true;
+ if (column === 'Assignee') return !!config.change.enable_assignee;
+ if (column === 'Comments') return experiments.includes('comments-column');
+ if (column === 'Reviewers') return !!config.change.enable_attention_set;
+ return true;
+ },
+
+ /**
+ * @param {!Array<string>} columns
+ * @param {Object} config
+ * @param {!Array<string>} experiments
+ * @return {!Array<string>} enabled columns, see isColumnEnabled().
+ */
+ getEnabledColumns(columns, config, experiments) {
+ return columns.filter(
+ col => this.isColumnEnabled(col, config, experiments));
+ },
+
+ /**
* The Project column was renamed to Repo, but some users may have
* preferences that use its old name. If that column is found, rename it
* before use.
diff --git a/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.html b/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.html
index 2889371..8036ff0 100644
--- a/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.html
@@ -65,6 +65,8 @@
'Status',
'Owner',
'Assignee',
+ 'Reviewers',
+ 'Comments',
'Repo',
'Branch',
'Updated',
@@ -76,6 +78,8 @@
'Subject',
'Status',
'Assignee',
+ 'Reviewers',
+ 'Comments',
'Repo',
'Branch',
'Size',
diff --git a/polygerrit-ui/app/behaviors/gr-display-name-behavior/gr-display-name-behavior.js b/polygerrit-ui/app/behaviors/gr-display-name-behavior/gr-display-name-behavior.js
index 2e7f5d4..af3ce64 100644
--- a/polygerrit-ui/app/behaviors/gr-display-name-behavior/gr-display-name-behavior.js
+++ b/polygerrit-ui/app/behaviors/gr-display-name-behavior/gr-display-name-behavior.js
@@ -29,6 +29,10 @@
return GrDisplayNameUtils.getUserName(config, account);
},
+ getDisplayName(config, account) {
+ return GrDisplayNameUtils.getDisplayName(config, account);
+ },
+
getGroupDisplayName(group) {
return GrDisplayNameUtils.getGroupDisplayName(group);
},
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
index 3605e15..69f2a44 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
@@ -26,6 +26,7 @@
import '../../shared/gr-change-star/gr-change-star.js';
import '../../shared/gr-change-status/gr-change-status.js';
import '../../shared/gr-date-formatter/gr-date-formatter.js';
+import '../../shared/gr-icons/gr-icons.js';
import '../../shared/gr-limited-text/gr-limited-text.js';
import '../../shared/gr-tooltip-content/gr-tooltip-content.js';
import '../../../styles/shared-styles.js';
@@ -208,6 +209,11 @@
}
}
+ _computeComments(unresolved_comment_count) {
+ if (!unresolved_comment_count || unresolved_comment_count < 1) return '';
+ return `${unresolved_comment_count} unresolved`;
+ }
+
/**
* TShirt sizing is based on the following paper:
* http://dirkriehle.com/wp-content/uploads/2008/09/hicss-42-csdistr-final-web.pdf
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_html.js b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_html.js
index f76189c..aed0077 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_html.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_html.js
@@ -52,6 +52,10 @@
white-space: nowrap;
width: 100%;
}
+ .comments,
+ .reviewers {
+ white-space: nowrap;
+ }
.spacer {
height: 0;
overflow: hidden;
@@ -101,6 +105,9 @@
.cell.label {
font-weight: var(--font-weight-normal);
}
+ .lastChildHidden:last-of-type {
+ display: none;
+ }
@media only screen and (max-width: 50em) {
:host {
display: flex;
@@ -150,6 +157,18 @@
<span class="placeholder">--</span>
</template>
</td>
+ <td class="cell reviewers" hidden\$="[[isColumnHidden('Reviewers', visibleChangeTableColumns)]]">
+ <div>
+ <template is="dom-repeat" items="[[change.reviewers.REVIEWER]]" as="reviewer">
+ <gr-account-link hide-avatar="" hide-status="" account="[[reviewer]]"></gr-account-link><!--
+ --><span class="lastChildHidden">, </span>
+ </template>
+ </div>
+ </td>
+ <td class="cell comments" hidden\$="[[isColumnHidden('Comments', visibleChangeTableColumns)]]">
+ <iron-icon hidden\$="[[!change.unresolved_comment_count]]" icon="gr-icons:comment"></iron-icon>
+ <span>[[_computeComments(change.unresolved_comment_count)]]</span>
+ </td>
<td class="cell repo" hidden\$="[[isColumnHidden('Repo', visibleChangeTableColumns)]]">
<a class="fullRepo" href\$="[[_computeRepoUrl(change)]]">
[[_computeRepoDisplay(change)]]
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
index d26fc17..b1479b6 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
@@ -124,6 +124,8 @@
'Status',
'Owner',
'Assignee',
+ 'Reviewers',
+ 'Comments',
'Repo',
'Branch',
'Updated',
@@ -148,6 +150,8 @@
'Status',
'Owner',
'Assignee',
+ 'Reviewers',
+ 'Comments',
'Branch',
'Updated',
'Size',
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
index ba7b366..a72faea 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
@@ -24,6 +24,7 @@
import '../../../styles/gr-change-list-styles.js';
import '../../core/gr-navigation/gr-navigation.js';
import '../../shared/gr-cursor-manager/gr-cursor-manager.js';
+import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../gr-change-list-item/gr-change-list-item.js';
import '../../../styles/shared-styles.js';
import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.js';
@@ -34,6 +35,7 @@
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-change-list_html.js';
+import {flags} from '../../../services/flags';
import {BaseUrlBehavior} from '../../../behaviors/base-url-behavior/base-url-behavior.js';
const NUMBER_FIXED_COLUMNS = 3;
@@ -131,13 +133,14 @@
changeTableColumns: Array,
visibleChangeTableColumns: Array,
preferences: Object,
+ _config: Object,
};
}
static get observers() {
return [
'_sectionsChanged(sections.*)',
- '_computePreferences(account, preferences)',
+ '_computePreferences(account, preferences, _config)',
];
}
@@ -165,6 +168,9 @@
ready() {
super.ready();
this._ensureAttribute('tabindex', 0);
+ this.$.restAPI.getConfig().then(config => {
+ this._config = config;
+ });
}
/** @override */
@@ -194,28 +200,26 @@
return column.toLowerCase();
}
- _computePreferences(account, preferences) {
+ _computePreferences(account, preferences, config) {
// Polymer 2: check for undefined
- if ([account, preferences].some(arg => arg === undefined)) {
+ if ([account, preferences, config].some(arg => arg === undefined)) {
return;
}
this.changeTableColumns = this.columnNames;
+ this.showNumber = false;
+ this.visibleChangeTableColumns = this.getEnabledColumns(this.columnNames,
+ config, flags.enabledExperiments);
if (account) {
this.showNumber = !!(preferences &&
preferences.legacycid_in_change_table);
if (preferences.change_table &&
preferences.change_table.length > 0) {
- this.visibleChangeTableColumns =
- this.getVisibleColumns(preferences.change_table);
- } else {
- this.visibleChangeTableColumns = this.columnNames;
+ const prefColumns = this.getVisibleColumns(preferences.change_table);
+ this.visibleChangeTableColumns = this.getEnabledColumns(prefColumns,
+ config, flags.enabledExperiments);
}
- } else {
- // Not logged in.
- this.showNumber = false;
- this.visibleChangeTableColumns = this.columnNames;
}
}
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_html.js b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_html.js
index ac37827..3309fb2 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_html.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_html.js
@@ -103,4 +103,5 @@
</template>
</table>
<gr-cursor-manager id="cursor" index="{{selectedIndex}}" scroll-behavior="keep-visible" focus-on-move=""></gr-cursor-manager>
+ <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
`;
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
index d077f6b..3bc7032 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
@@ -69,6 +69,7 @@
element = fixture('basic');
element.account = null;
element.preferences = null;
+ element._config = {};
});
test('show number disabled', () => {
@@ -85,6 +86,7 @@
change_table: [],
};
element.account = {_account_id: 1001};
+ element._config = {};
flushAsynchronousOperations();
});
@@ -102,6 +104,7 @@
change_table: [],
};
element.account = {_account_id: 1001};
+ element._config = {};
flushAsynchronousOperations();
});
@@ -334,6 +337,7 @@
time_format: 'HHMM_12',
change_table: [],
};
+ element._config = {};
flushAsynchronousOperations();
});
@@ -367,12 +371,15 @@
'Status',
'Owner',
'Assignee',
+ 'Reviewers',
+ 'Comments',
'Repo',
'Branch',
'Updated',
'Size',
],
};
+ element._config = {};
flushAsynchronousOperations();
});
@@ -402,11 +409,14 @@
'Status',
'Owner',
'Assignee',
+ 'Reviewers',
+ 'Comments',
'Branch',
'Updated',
'Size',
],
};
+ element._config = {};
flushAsynchronousOperations();
});
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
index 2c023752..fabcdad 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.js
@@ -105,14 +105,6 @@
];
}
- get options() {
- return this.listChangesOptionsToHex(
- this.ListChangesOption.LABELS,
- this.ListChangesOption.DETAILED_ACCOUNTS,
- this.ListChangesOption.REVIEWED
- );
- }
-
/** @override */
attached() {
super.attached();
@@ -240,7 +232,7 @@
queries.push('owner:self limit:1');
}
- return this.$.restAPI.getChanges(null, queries, null, this.options)
+ return this.$.restAPI.getChanges(null, queries)
.then(changes => {
if (checkForNewUser) {
// Last set of results is not meant for dashboard display.
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
index 8a0cfa0..f94c896 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
@@ -206,8 +206,7 @@
};
return paramsChangedPromise.then(() => {
assert.isTrue(
- getChangesStub.calledWith(
- null, ['1', '2', 'owner:self limit:1'], null, element.options));
+ getChangesStub.calledWith(null, ['1', '2', 'owner:self limit:1']));
});
});
@@ -221,9 +220,7 @@
user: 'user',
};
return paramsChangedPromise.then(() => {
- assert.isTrue(
- getChangesStub.calledWith(
- null, ['1'], null, element.options));
+ assert.isTrue(getChangesStub.calledWith(null, ['1']));
});
});
});
@@ -239,8 +236,7 @@
return paramsChangedPromise.then(() => {
assert.isTrue(getChangesStub.calledOnce);
assert.deepEqual(
- getChangesStub.firstCall.args,
- [null, ['1', '2 suffix'], null, element.options]);
+ getChangesStub.firstCall.args, [null, ['1', '2 suffix']]);
});
});
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html
index 160b912..47e6a9a 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html
@@ -46,7 +46,6 @@
let element;
const sectionSelectors = [
- 'section.assignee',
'section.strategy',
'section.topic',
];
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
index 2e9cdf9..28262be 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -188,7 +188,9 @@
}
_assigneeChanged(assigneeRecord) {
- if (!this.change) { return; }
+ if (!this.change || !this._isAssigneeEnabled(this.serverConfig)) {
+ return;
+ }
const assignee = assigneeRecord.base;
if (assignee.length) {
const acct = assignee[0];
@@ -225,6 +227,11 @@
return weblinks.length ? weblinks : null;
}
+ _isAssigneeEnabled(serverConfig) {
+ return serverConfig && serverConfig.change
+ && !!serverConfig.change.enable_assignee;
+ }
+
_computeStrategy(change) {
return SubmitTypeLabel[change.submit_type];
}
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_html.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_html.js
index 786a118..059aa71 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_html.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_html.js
@@ -97,6 +97,9 @@
.topic gr-linked-chip {
--linked-chip-text-color: var(--link-color);
}
+ gr-reviewer-list {
+ max-width: 200px;
+ }
</style>
<gr-external-style id="externalStyle" name="change-metadata">
<section>
@@ -135,23 +138,25 @@
<gr-account-link account="[[_getNonOwnerRole(change, _CHANGE_ROLE.COMMITTER)]]"></gr-account-link>
</span>
</section>
- <section class="assignee">
- <span class="title">Assignee</span>
- <span class="value">
- <gr-account-list id="assigneeValue" placeholder="Set assignee..." max-count="1" skip-suggest-on-empty="" accounts="{{_assignee}}" readonly="[[_computeAssigneeReadOnly(_mutable, change)]]" suggestions-provider="[[_getReviewerSuggestionsProvider(change)]]">
- </gr-account-list>
- </span>
- </section>
+ <template is="dom-if" if="[[_isAssigneeEnabled(serverConfig)]]">
+ <section class="assignee">
+ <span class="title">Assignee</span>
+ <span class="value">
+ <gr-account-list id="assigneeValue" placeholder="Set assignee..." max-count="1" skip-suggest-on-empty="" accounts="{{_assignee}}" readonly="[[_computeAssigneeReadOnly(_mutable, change)]]" suggestions-provider="[[_getReviewerSuggestionsProvider(change)]]">
+ </gr-account-list>
+ </span>
+ </section>
+ </template>
<section>
<span class="title">Reviewers</span>
<span class="value">
- <gr-reviewer-list change="{{change}}" mutable="[[_mutable]]" reviewers-only="" max-reviewers-displayed="3"></gr-reviewer-list>
+ <gr-reviewer-list change="{{change}}" mutable="[[_mutable]]" reviewers-only="" server-config="[[serverConfig]]"></gr-reviewer-list>
</span>
</section>
<section>
<span class="title">CC</span>
<span class="value">
- <gr-reviewer-list change="{{change}}" mutable="[[_mutable]]" ccs-only="" max-reviewers-displayed="3"></gr-reviewer-list>
+ <gr-reviewer-list change="{{change}}" mutable="[[_mutable]]" ccs-only="" server-config="[[serverConfig]]"></gr-reviewer-list>
</span>
</section>
<template is="dom-if" if="[[_computeShowRepoBranchTogether(change.project, change.branch)]]">
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
index 773e6ec..ce3770f 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
@@ -634,6 +634,11 @@
setup(() => {
deleteStub = sandbox.stub(element.$.restAPI, 'deleteAssignee');
setStub = sandbox.stub(element.$.restAPI, 'setAssignee');
+ element.serverConfig = {
+ change: {
+ enable_assignee: true,
+ },
+ };
});
test('changing change recomputes _assignee', () => {
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.js b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.js
index 129cb01..0fcf81d 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.js
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.js
@@ -44,6 +44,7 @@
static get properties() {
return {
change: Object,
+ serverConfig: Object,
disabled: {
type: Boolean,
value: false,
@@ -61,7 +62,6 @@
type: Boolean,
value: false,
},
- maxReviewersDisplayed: Number,
_displayedReviewers: {
type: Array,
@@ -92,7 +92,7 @@
static get observers() {
return [
- '_reviewersChanged(change.reviewers.*, change.owner)',
+ '_reviewersChanged(change.reviewers.*, change.owner, serverConfig)',
];
}
@@ -179,9 +179,9 @@
return maxScores.join(', ');
}
- _reviewersChanged(changeRecord, owner) {
+ _reviewersChanged(changeRecord, owner, serverConfig) {
// Polymer 2: check for undefined
- if ([changeRecord, owner].some(arg => arg === undefined)) {
+ if ([changeRecord, owner, serverConfig].some(arg => arg === undefined)) {
return;
}
@@ -201,12 +201,13 @@
this._reviewers = result
.filter(reviewer => reviewer._account_id != owner._account_id);
+ const isFirstNameConfigured = serverConfig.accounts
+ && serverConfig.accounts.default_display_name === 'FIRST_NAME';
+ const maxReviewers = isFirstNameConfigured ? 6 : 3;
// If there is one or two more than the max reviewers, don't show the
// 'show more' button, because it takes up just as much space.
- if (this.maxReviewersDisplayed &&
- this._reviewers.length > this.maxReviewersDisplayed + 2) {
- this._displayedReviewers =
- this._reviewers.slice(0, this.maxReviewersDisplayed);
+ if (this._reviewers.length > maxReviewers + 2) {
+ this._displayedReviewers = this._reviewers.slice(0, maxReviewers);
} else {
this._displayedReviewers = this._reviewers;
}
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_html.js b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_html.js
index c5df61d..300e38a 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_html.js
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_html.js
@@ -27,26 +27,27 @@
}
.container {
display: block;
- /* This is a bit of a hack. We tried to use margin-top with
- :not(:first-child) before, but :first-child does not understand
- whether a child is visible or not. So adding a margin for every
- child and then a negative one at the top does the trick. */
- margin-top: calc(0px - var(--spacing-s));
- }
- .container > * {
- margin-top: var(--spacing-s);
}
gr-button {
--gr-button: {
padding: 0px 0px;
}
}
+ gr-account-chip {
+ display: inline-block;
+ }
</style>
<div class="container">
- <template is="dom-repeat" items="[[_displayedReviewers]]" as="reviewer">
- <gr-account-chip class="reviewer" account="[[reviewer]]" on-remove="_handleRemove" voteable-text="[[_computeVoteableText(reviewer, change)]]" removable="[[_computeCanRemoveReviewer(reviewer, mutable)]]">
- </gr-account-chip>
- </template>
+ <div>
+ <template is="dom-repeat" items="[[_displayedReviewers]]" as="reviewer">
+ <gr-account-chip class="reviewer"
+ account="[[reviewer]]"
+ on-remove="_handleRemove"
+ voteable-text="[[_computeVoteableText(reviewer, change)]]"
+ removable="[[_computeCanRemoveReviewer(reviewer, mutable)]]">
+ </gr-account-chip>
+ </template>
+ </div>
<gr-button class="hiddenReviewers" link="" hidden\$="[[!_hiddenReviewerCount]]" on-click="_handleViewAll">and [[_hiddenReviewerCount]] more</gr-button>
<div class="controlsContainer" hidden\$="[[!mutable]]">
<gr-button link="" id="addReviewer" class="addReviewer" on-click="_handleAddTap">[[_addLabel]]</gr-button>
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html
index d97bf6b..9e51d16 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html
@@ -40,6 +40,7 @@
setup(() => {
element = fixture('basic');
+ element.serverConfig = {};
sandbox = sinon.sandbox.create();
stub('gr-rest-api-interface', {
getConfig() { return Promise.resolve({}); },
@@ -198,9 +199,32 @@
{value: {ccsOnly: true}});
});
- test('no show all reviewers button with 6 reviewers', () => {
+ test('dont show all reviewers button with 4 reviewers', () => {
const reviewers = [];
- element.maxReviewersDisplayed = 5;
+ element.maxReviewersDisplayed = 3;
+ for (let i = 0; i < 4; i++) {
+ reviewers.push(
+ {email: i+'reviewer@google.com', name: 'reviewer-' + i});
+ }
+ element.ccsOnly = true;
+
+ element.change = {
+ owner: {
+ _account_id: 1,
+ },
+ reviewers: {
+ CC: reviewers,
+ },
+ };
+ assert.equal(element._hiddenReviewerCount, 0);
+ assert.equal(element._displayedReviewers.length, 4);
+ assert.equal(element._reviewers.length, 4);
+ assert.isTrue(element.shadowRoot
+ .querySelector('.hiddenReviewers').hidden);
+ });
+
+ test('show all reviewers button with 6 reviewers', () => {
+ const reviewers = [];
for (let i = 0; i < 6; i++) {
reviewers.push(
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
@@ -215,63 +239,15 @@
CC: reviewers,
},
};
- assert.equal(element._hiddenReviewerCount, 0);
- assert.equal(element._displayedReviewers.length, 6);
- assert.equal(element._reviewers.length, 6);
- assert.isTrue(element.shadowRoot
- .querySelector('.hiddenReviewers').hidden);
- });
-
- test('show all reviewers button with 8 reviewers', () => {
- const reviewers = [];
- element.maxReviewersDisplayed = 5;
- for (let i = 0; i < 8; i++) {
- reviewers.push(
- {email: i+'reviewer@google.com', name: 'reviewer-' + i});
- }
- element.ccsOnly = true;
-
- element.change = {
- owner: {
- _account_id: 1,
- },
- reviewers: {
- CC: reviewers,
- },
- };
assert.equal(element._hiddenReviewerCount, 3);
- assert.equal(element._displayedReviewers.length, 5);
- assert.equal(element._reviewers.length, 8);
+ assert.equal(element._displayedReviewers.length, 3);
+ assert.equal(element._reviewers.length, 6);
assert.isFalse(element.shadowRoot
.querySelector('.hiddenReviewers').hidden);
});
- test('no maxReviewersDisplayed', () => {
- const reviewers = [];
- for (let i = 0; i < 7; i++) {
- reviewers.push(
- {email: i+'reviewer@google.com', name: 'reviewer-' + i});
- }
- element.ccsOnly = true;
-
- element.change = {
- owner: {
- _account_id: 1,
- },
- reviewers: {
- CC: reviewers,
- },
- };
- assert.equal(element._hiddenReviewerCount, 0);
- assert.equal(element._displayedReviewers.length, 7);
- assert.equal(element._reviewers.length, 7);
- assert.isTrue(element.shadowRoot
- .querySelector('.hiddenReviewers').hidden);
- });
-
test('show all reviewers button', () => {
const reviewers = [];
- element.maxReviewersDisplayed = 5;
for (let i = 0; i < 100; i++) {
reviewers.push(
{email: i+'reviewer@google.com', name: 'reviewer-' + i});
@@ -286,8 +262,8 @@
CC: reviewers,
},
};
- assert.equal(element._hiddenReviewerCount, 95);
- assert.equal(element._displayedReviewers.length, 5);
+ assert.equal(element._hiddenReviewerCount, 97);
+ assert.equal(element._displayedReviewers.length, 3);
assert.equal(element._reviewers.length, 100);
assert.isFalse(element.shadowRoot
.querySelector('.hiddenReviewers').hidden);
diff --git a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html
index 287ac3b..919be86 100644
--- a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html
@@ -47,6 +47,8 @@
'Status',
'Owner',
'Assignee',
+ 'Reviewers',
+ 'Comments',
'Repo',
'Branch',
'Updated',
diff --git a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.js b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.js
index c4f9119..274f270 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.js
@@ -61,6 +61,10 @@
type: Boolean,
value: false,
},
+ showAttention: {
+ type: Boolean,
+ value: false,
+ },
showAvatar: {
type: Boolean,
reflectToAttribute: true,
diff --git a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip_html.js b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip_html.js
index 14bbd57..cfa0243 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip_html.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip_html.js
@@ -81,7 +81,9 @@
}
</style>
<div class\$="container [[_getBackgroundClass(transparentBackground)]]">
- <gr-account-link account="[[account]]" voteable-text="[[voteableText]]">
+ <gr-account-link account="[[account]]"
+ show-attention="[[showAttention]]"
+ voteable-text="[[voteableText]]">
</gr-account-link>
<gr-button id="remove" link="" hidden\$="[[!removable]]" hidden="" tabindex="-1" aria-label="Remove" class\$="remove [[_getBackgroundClass(transparentBackground)]]" on-click="_handleRemoveTap">
<iron-icon icon="gr-icons:close"></iron-icon>
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.js b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.js
index d279563..ef835f0 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.js
@@ -50,10 +50,18 @@
*/
account: Object,
voteableText: String,
+ showAttention: {
+ type: Boolean,
+ value: false,
+ },
hideAvatar: {
type: Boolean,
value: false,
},
+ hideStatus: {
+ type: Boolean,
+ value: false,
+ },
_serverConfig: {
type: Object,
value: null,
@@ -69,7 +77,7 @@
}
_computeName(account, config) {
- return this.getUserName(config, account);
+ return this.getDisplayName(config, account);
}
}
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_html.js b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_html.js
index a7d01ae..f642af3 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_html.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_html.js
@@ -20,10 +20,23 @@
<style include="shared-styles">
:host {
display: inline;
+ position: relative;
}
:host::after {
content: var(--account-label-suffix);
}
+ :host(:not([blurred])) .overlay {
+ display: none;
+ }
+ .overlay {
+ position: absolute;
+ pointer-events: none;
+ height: var(--line-height-normal);
+ right: 0;
+ left: 0;
+ background-color: var(--background-color-primary);
+ opacity: 0.5;
+ }
gr-avatar {
height: var(--line-height-normal);
width: var(--line-height-normal);
@@ -35,7 +48,10 @@
.text:hover {
@apply --gr-account-label-text-hover-style;
}
- iron-icon {
+ iron-icon.attention {
+ vertical-align: top;
+ }
+ iron-icon.status {
width: 14px;
height: 14px;
vertical-align: top;
@@ -43,16 +59,25 @@
top: 2px;
}
</style>
+ <div class="overlay"></div>
<span>
- <gr-hovercard-account account="[[account]]" voteable-text="[[voteableText]]"></gr-hovercard-account>
- <template is="dom-if" if="[[!hideAvatar]]">
- <gr-avatar account="[[account]]" image-size="32"></gr-avatar>
+ <gr-hovercard-account attention="[[showAttention]]"
+ account="[[account]]"
+ voteable-text="[[voteableText]]">
+ </gr-hovercard-account>
+ <template is="dom-if" if="[[showAttention]]">
+ <iron-icon class="attention" icon="gr-icons:attention"></iron-icon><!--
+ --></template><!--
+ --><template is="dom-if" if="[[!hideAvatar]]"><!--
+ --><gr-avatar account="[[account]]" image-size="32"></gr-avatar>
</template>
<span class="text">
<span class="name">
[[_computeName(account, _serverConfig)]]</span>
- <template is="dom-if" if="[[account.status]]">
- <iron-icon icon="gr-icons:calendar"></iron-icon>
+ <template is="dom-if" if="[[!hideStatus]]">
+ <template is="dom-if" if="[[account.status]]">
+ <iron-icon class="status" icon="gr-icons:calendar"></iron-icon>
+ </template>
</template>
</span>
</span>
diff --git a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.js b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.js
index a5738d1..ca37659 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.js
@@ -42,6 +42,18 @@
return {
voteableText: String,
account: Object,
+ showAttention: {
+ type: Boolean,
+ value: false,
+ },
+ hideAvatar: {
+ type: Boolean,
+ value: false,
+ },
+ hideStatus: {
+ type: Boolean,
+ value: false,
+ },
};
}
diff --git a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_html.js b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_html.js
index 4f1ea44..5eb9ad5 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_html.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_html.js
@@ -33,7 +33,12 @@
</style>
<span>
<a href\$="[[_computeOwnerLink(account)]]" tabindex="-1">
- <gr-account-label account="[[account]]" voteable-text="[[voteableText]]"></gr-account-label>
+ <gr-account-label show-attention="[[showAttention]]"
+ hide-avatar="[[hideAvatar]]"
+ hide-status="[[hideStatus]]"
+ account="[[account]]"
+ voteable-text="[[voteableText]]">
+ </gr-account-label>
</a>
</span>
`;
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index 914a1ad..a4308c4 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -950,49 +950,50 @@
* changeInfos.
*/
getChanges(opt_changesPerPage, opt_query, opt_offset, opt_options) {
- const options = opt_options || this.listChangesOptionsToHex(
- this.ListChangesOption.LABELS,
- this.ListChangesOption.DETAILED_ACCOUNTS
- );
- // Issue 4524: respect legacy token with max sortkey.
- if (opt_offset === 'n,z') {
- opt_offset = 0;
- }
- const params = {
- O: options,
- S: opt_offset || 0,
- };
- if (opt_changesPerPage) { params.n = opt_changesPerPage; }
- if (opt_query && opt_query.length > 0) {
- params.q = opt_query;
- }
- const iterateOverChanges = arr => {
- for (const change of (arr || [])) {
- this._maybeInsertInLookup(change);
- }
- };
- const req = {
- url: '/changes/',
- params,
- reportUrlAsIs: true,
- };
- return this._restApiHelper.fetchJSON(req).then(response => {
- // Response may be an array of changes OR an array of arrays of
- // changes.
- if (opt_query instanceof Array) {
- // Normalize the response to look like a multi-query response
- // when there is only one query.
- if (opt_query.length === 1) {
- response = [response];
- }
- for (const arr of response) {
- iterateOverChanges(arr);
- }
- } else {
- iterateOverChanges(response);
- }
- return response;
- });
+ return this.getConfig(false)
+ .then(config => {
+ const options = opt_options || this._getChangesOptionsHex(config);
+ // Issue 4524: respect legacy token with max sortkey.
+ if (opt_offset === 'n,z') {
+ opt_offset = 0;
+ }
+ const params = {
+ O: options,
+ S: opt_offset || 0,
+ };
+ if (opt_changesPerPage) { params.n = opt_changesPerPage; }
+ if (opt_query && opt_query.length > 0) {
+ params.q = opt_query;
+ }
+ return {
+ url: '/changes/',
+ params,
+ reportUrlAsIs: true,
+ };
+ })
+ .then(req => this._restApiHelper.fetchJSON(req))
+ .then(response => {
+ const iterateOverChanges = arr => {
+ for (const change of (arr || [])) {
+ this._maybeInsertInLookup(change);
+ }
+ };
+ // Response may be an array of changes OR an array of arrays of
+ // changes.
+ if (opt_query instanceof Array) {
+ // Normalize the response to look like a multi-query response
+ // when there is only one query.
+ if (opt_query.length === 1) {
+ response = [response];
+ }
+ for (const arr of response) {
+ iterateOverChanges(arr);
+ }
+ } else {
+ iterateOverChanges(response);
+ }
+ return response;
+ });
}
/**
@@ -1034,6 +1035,20 @@
});
}
+ _getChangesOptionsHex(config) {
+ const options = [
+ this.ListChangesOption.LABELS,
+ this.ListChangesOption.DETAILED_ACCOUNTS,
+ ];
+ if (config && config.change && config.change.enable_attention_set) {
+ options.push(this.ListChangesOption.DETAILED_LABELS);
+ } else {
+ options.push(this.ListChangesOption.REVIEWED);
+ }
+
+ return this.listChangesOptionsToHex(...options);
+ }
+
_getChangeOptionsHex(config) {
if (window.DEFAULT_DETAIL_HEXES && window.DEFAULT_DETAIL_HEXES.changePage
&& !(config.receive && config.receive.enable_signed_push)) {
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html
index 814a474..5fd289e 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html
@@ -332,10 +332,11 @@
});
});
- test('legacy n,z key in change url is replaced', () => {
+ test('legacy n,z key in change url is replaced', async () => {
+ sandbox.stub(element, 'getConfig', async () => { return {}; });
const stub = sandbox.stub(element._restApiHelper, 'fetchJSON')
.returns(Promise.resolve([]));
- element.getChanges(1, null, 'n,z');
+ await element.getChanges(1, null, 'n,z');
assert.equal(stub.lastCall.args[0].params.S, 0);
});
diff --git a/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils.js b/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils.js
index cefd254..20de3fb6 100644
--- a/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils.js
+++ b/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils.js
@@ -39,6 +39,24 @@
return ANONYMOUS_NAME;
}
+ static getDisplayName(config, account) {
+ if (account && account.display_name) {
+ return account.display_name;
+ }
+ if (!account || !account.name || !config || !config.accounts) {
+ return this.getUserName(config, account);
+ }
+ if (config.accounts.default_display_name === 'USERNAME'
+ && account.username) {
+ return account.username;
+ }
+ if (config.accounts.default_display_name === 'FIRST_NAME') {
+ return account.name.trim().split(' ')[0];
+ }
+ // Treat every other value as FULL_NAME.
+ return account.name;
+ }
+
static getAccountDisplayName(config, account) {
const reviewerName = this.getUserName(config, account);
const reviewerEmail = this._accountEmail(account.email);
diff --git a/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils_test.html b/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils_test.html
index 262d53c..0ed5ec7 100644
--- a/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils_test.html
+++ b/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils_test.html
@@ -34,7 +34,77 @@
},
};
- test('getUserName name only', () => {
+ test('getDisplayName name only', () => {
+ const account = {
+ name: 'test-name',
+ };
+ assert.equal(GrDisplayNameUtils.getDisplayName(config, account),
+ 'test-name');
+ });
+
+ test('getDisplayName prefer displayName', () => {
+ const account = {
+ name: 'test-name',
+ display_name: 'better-name',
+ };
+ assert.equal(GrDisplayNameUtils.getDisplayName(config, account),
+ 'better-name');
+ });
+
+ test('getDisplayName prefer username default', () => {
+ const account = {
+ name: 'test-name',
+ username: 'user-name',
+ };
+ const config = {
+ accounts: {
+ default_display_name: 'USERNAME',
+ },
+ };
+ assert.equal(GrDisplayNameUtils.getDisplayName(config, account),
+ 'user-name');
+ });
+
+ test('getDisplayName prefer first name default', () => {
+ const account = {
+ name: 'firstname lastname',
+ };
+ const config = {
+ accounts: {
+ default_display_name: 'FIRST_NAME',
+ },
+ };
+ assert.equal(GrDisplayNameUtils.getDisplayName(config, account),
+ 'firstname');
+ });
+
+ test('getDisplayName ignore leading whitespace for first name', () => {
+ const account = {
+ name: ' firstname lastname',
+ };
+ const config = {
+ accounts: {
+ default_display_name: 'FIRST_NAME',
+ },
+ };
+ assert.equal(GrDisplayNameUtils.getDisplayName(config, account),
+ 'firstname');
+ });
+
+ test('getDisplayName full name default', () => {
+ const account = {
+ name: 'firstname lastname',
+ };
+ const config = {
+ accounts: {
+ default_display_name: 'FULL_NAME',
+ },
+ };
+ assert.equal(GrDisplayNameUtils.getDisplayName(config, account),
+ 'firstname lastname');
+ });
+
+ test('getDisplayName name only', () => {
const account = {
name: 'test-name',
};
diff --git a/polygerrit-ui/app/styles/gr-change-list-styles.js b/polygerrit-ui/app/styles/gr-change-list-styles.js
index 148943b..4f4d7e3 100644
--- a/polygerrit-ui/app/styles/gr-change-list-styles.js
+++ b/polygerrit-ui/app/styles/gr-change-list-styles.js
@@ -89,6 +89,9 @@
.star {
width: 30px;
}
+ .reviewers div {
+ overflow: hidden;
+ }
.label, .endpoint {
border-left: 1px solid var(--border-color);
}
@@ -118,7 +121,8 @@
@media only screen and (max-width: 100em) {
.assignee,
.branch,
- .owner {
+ .owner,
+ .reviewers {
max-width: 10rem;
}
}
diff --git a/polygerrit-ui/app/styles/gr-change-metadata-shared-styles.js b/polygerrit-ui/app/styles/gr-change-metadata-shared-styles.js
index 51cf6d3..aabdde5 100644
--- a/polygerrit-ui/app/styles/gr-change-metadata-shared-styles.js
+++ b/polygerrit-ui/app/styles/gr-change-metadata-shared-styles.js
@@ -34,6 +34,7 @@
.title,
.value {
display: table-cell;
+ vertical-align: top;
}
.title {
@@ -43,10 +44,6 @@
padding-right: var(--metadata-horizontal-padding);
word-break: break-word;
}
-
- .value {
- padding-right: var(--metadata-horizontal-padding);
- }
</style>
</template>
</dom-module>`;