Merge "Handle network failures during project lookup"
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
index 2d8da15..ae28a05 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
@@ -60,6 +60,10 @@
type: Boolean,
value: false,
},
+ _isAdmin: {
+ type: Boolean,
+ value: false,
+ },
_showGroup: Boolean,
_showGroupAuditLog: Boolean,
_showGroupList: Boolean,
@@ -155,7 +159,7 @@
},
],
};
- if (this._groupOwner) {
+ if (this._isAdmin || this._groupOwner) {
linkCopy.subsection.children.push(
{
name: 'Audit Log',
@@ -242,16 +246,20 @@
_computeGroupName(groupId) {
if (!groupId) { return ''; }
+ const promises = [];
this.$.restAPI.getGroupConfig(groupId).then(group => {
this._groupName = group.name;
this.reload();
- this.$.restAPI.getIsGroupOwner(group.name).then(
+ promises.push(this.$.restAPI.getIsAdmin().then(isAdmin => {
+ this._isAdmin = isAdmin;
+ }));
+ promises.push(this.$.restAPI.getIsGroupOwner(group.name).then(
isOwner => {
- if (isOwner) {
- this._groupOwner = true;
- this.reload();
- }
- });
+ this._groupOwner = isOwner;
+ }));
+ return Promise.all(promises).then(() => {
+ this.reload();
+ });
});
},
diff --git a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.html b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.html
index 9371b17..9e08381 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.html
+++ b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.html
@@ -67,9 +67,18 @@
font-family: var(--font-family-bold);
text-align: left;
}
+ .canModify #groupMemberSearchInput,
+ .canModify #saveGroupMember,
+ .canModify .deleteHeader,
+ .canModify .deleteColumn,
+ .canModify #includedGroupSearchInput,
+ .canModify #saveIncludedGroups,
+ .canModify .deleteIncludedHeader,
+ .canModify #saveIncludedGroups {
+ display: none;
+ }
</style>
- <style include="gr-form-styles"></style>
- <main class="gr-form-styles">
+ <main class$="gr-form-styles [[_computeHideItemClass(_groupOwner, _isAdmin)]]">
<div id="loading" class$="[[_computeLoadingClass(_loading)]]">
Loading...
</div>
@@ -84,15 +93,13 @@
id="groupMemberSearchInput"
text="{{_groupMemberSearch}}"
query="[[_queryMembers]]"
- placeholder="Name Or Email"
- hidden$="[[!_groupOwner]]">
+ placeholder="Name Or Email">
</gr-autocomplete>
</span>
<gr-button
id="saveGroupMember"
on-tap="_handleSavingGroupMember"
- disabled="[[!_groupMemberSearch]]"
- hidden$="[[!_groupOwner]]">
+ disabled="[[!_groupMemberSearch]]">
Add
</gr-button>
<div class="gr-form-styles">
@@ -100,9 +107,7 @@
<tr class="headerRow">
<th class="nameHeader">Name</th>
<th class="emailAddressHeader">Email Address</th>
- <th class="deleteHeader" hidden$="[[!_groupOwner]]">
- Delete Member
- </th>
+ <th class="deleteHeader">Delete Member</th>
</tr>
<tbody>
<template is="dom-repeat" items="[[_groupMembers]]">
@@ -111,7 +116,7 @@
<gr-account-link account="[[item]]"></gr-account-link>
</td>
<td>[[item.email]]</td>
- <td hidden$="[[!_groupOwner]]">
+ <td class="deleteColumn">
<gr-button
class="deleteButton"
on-tap="_handleDeleteMember">
@@ -133,15 +138,13 @@
id="includedGroupSearchInput"
text="{{_includedGroupSearch}}"
query="[[_queryIncludedGroup]]"
- placeholder="Group Name"
- hidden$="[[!_groupOwner]]">
+ placeholder="Group Name">
</gr-autocomplete>
</span>
<gr-button
id="saveIncludedGroups"
on-tap="_handleSavingIncludedGroups"
- disabled="[[!_includedGroupSearch]]"
- hidden$="[[!_groupOwner]]">
+ disabled="[[!_includedGroupSearch]]">
Add
</gr-button>
<div class="gr-form-styles">
@@ -149,7 +152,7 @@
<tr class="headerRow">
<th class="groupNameHeader">Group Name</th>
<th class="descriptionHeader">Description</th>
- <th class="deleteIncludedHeader" hidden$="[[!_groupOwner]]">
+ <th class="deleteIncludedHeader">
Delete Included Group
</th>
</tr>
@@ -162,7 +165,7 @@
</a>
</td>
<td>[[item.description]]</td>
- <td hidden$="[[!_groupOwner]]">
+ <td class="deleteColumn">
<gr-button
class="deleteIncludedGroupButton"
on-tap="_handleDeleteIncludedGroup">
diff --git a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js
index cde6c66..81bb902 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js
+++ b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js
@@ -48,6 +48,10 @@
type: Boolean,
value: false,
},
+ _isAdmin: {
+ type: Boolean,
+ value: false,
+ },
},
behaviors: [
@@ -68,17 +72,29 @@
return this.$.restAPI.getGroupConfig(this.groupId).then(
config => {
+ if (!config.name) { return; }
+
this._groupName = config.name;
+
+ promises.push(this.$.restAPI.getIsAdmin().then(isAdmin => {
+ this._isAdmin = isAdmin ? true : false;
+ }));
+
promises.push(this.$.restAPI.getIsGroupOwner(config.name)
- .then(isOwner => { this._groupOwner = isOwner; }));
+ .then(isOwner => {
+ this._groupOwner = isOwner ? true : false;
+ }));
+
promises.push(this.$.restAPI.getGroupMembers(config.name).then(
members => {
this._groupMembers = members;
}));
+
promises.push(this.$.restAPI.getIncludedGroup(config.name)
.then(includedGroup => {
this._includedGroups = includedGroup;
}));
+
return Promise.all(promises).then(() => {
this._loading = false;
});
@@ -223,5 +239,9 @@
return groups;
});
},
+
+ _computeHideItemClass(owner, admin) {
+ return admin || owner ? '' : 'canModify';
+ },
});
})();
diff --git a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.html b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.html
index 76a182b..ef89e37 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.html
@@ -152,5 +152,23 @@
done();
});
});
+
+ test('_computeHideItemClass returns string for admin', () => {
+ const admin = true;
+ const owner = false;
+ assert.equal(element._computeHideItemClass(owner, admin), '');
+ });
+
+ test('_computeHideItemClass returns hideItem for admin and owner', () => {
+ const admin = false;
+ const owner = false;
+ assert.equal(element._computeHideItemClass(owner, admin), 'canModify');
+ });
+
+ test('_computeHideItemClass returns string for owner', () => {
+ const admin = false;
+ const owner = true;
+ assert.equal(element._computeHideItemClass(owner, admin), '');
+ });
});
</script>
diff --git a/polygerrit-ui/app/elements/admin/gr-group/gr-group.html b/polygerrit-ui/app/elements/admin/gr-group/gr-group.html
index 2f3d59a..0449ffa 100644
--- a/polygerrit-ui/app/elements/admin/gr-group/gr-group.html
+++ b/polygerrit-ui/app/elements/admin/gr-group/gr-group.html
@@ -71,13 +71,15 @@
<gr-autocomplete
id="groupNameInput"
text="{{_groupConfig.name}}"
- disabled="[[!_groupOwner]]"></gr-autocomplete>
+ disabled="[[_computeGroupDisabled(_groupOwner, _isAdmin)]]"></gr-autocomplete>
</span>
- <gr-button
- id="inputUpdateNameBtn"
- on-tap="_handleSaveName"
- disabled="[[_computeButtonDisabled(_groupOwner, _rename)]]">
- Rename Group</gr-button>
+ <span class="value" disabled$="[[_computeGroupDisabled(_groupOwner, _isAdmin)]]">
+ <gr-button
+ id="inputUpdateNameBtn"
+ on-tap="_handleSaveName"
+ disabled="[[!_rename]]">
+ Rename Group</gr-button>
+ </span>
</fieldset>
<h3 class$="[[_computeHeaderClass(_owner)]]">
Owners
@@ -87,13 +89,15 @@
<gr-autocomplete
text="{{_groupConfig.owner}}"
query="[[_query]]"
- disabled$="[[!_groupOwner]]">
+ disabled="[[_computeGroupDisabled(_groupOwner, _isAdmin)]]">
</gr-autocomplete>
</span>
- <gr-button
- on-tap="_handleSaveOwner"
- disabled="[[_computeButtonDisabled(_groupOwner, _owner)]]">
- Change Owners</gr-button>
+ <span class="value" disabled$="[[_computeGroupDisabled(_groupOwner, _isAdmin)]]">
+ <gr-button
+ on-tap="_handleSaveOwner"
+ disabled="[[!_owner]]">
+ Change Owners</gr-button>
+ </span>
</fieldset>
<h3 class$="[[_computeHeaderClass(_description)]]">
Description
@@ -104,14 +108,15 @@
class="description"
autocomplete="on"
bind-value="{{_groupConfig.description}}"
- disabled="[[!_groupOwner]]"></iron-autogrow-textarea>
+ disabled="[[_computeGroupDisabled(_groupOwner, _isAdmin)]]"></iron-autogrow-textarea>
</div>
- <gr-button
- on-tap="_handleSaveDescription"
- disabled=
- "[[_computeButtonDisabled(_groupOwner, _description)]]">
- Save Description
- </gr-button>
+ <span class="value" disabled$="[[_computeGroupDisabled(_groupOwner, _isAdmin)]]">
+ <gr-button
+ on-tap="_handleSaveDescription"
+ disabled="[[!_description]]">
+ Save Description
+ </gr-button>
+ </span>
</fieldset>
<h3 id="options" class$="[[_computeHeaderClass(_options)]]">
Group Options
@@ -124,7 +129,7 @@
<span class="value">
<gr-select
bind-value="{{_groupConfig.options.visible_to_all}}">
- <select disabled$="[[!_groupOwner]]">
+ <select disabled$="[[_computeGroupDisabled(_groupOwner, _isAdmin)]]">
<template is="dom-repeat" items="[[_submitTypes]]">
<option value="[[item.value]]">[[item.label]]</option>
</template>
@@ -132,12 +137,13 @@
</gr-select>
</span>
</section>
- <gr-button
- on-tap="_handleSaveOptions"
- disabled=
- "[[_computeButtonDisabled(_groupOwner, _options)]]">
- Save Group Options
- </gr-button>
+ <span class="value" disabled$="[[_computeGroupDisabled(_groupOwner, _isAdmin)]]">
+ <gr-button
+ on-tap="_handleSaveOptions"
+ disabled="[[!_options]]">
+ Save Group Options
+ </gr-button>
+ </span>
</fieldset>
</fieldset>
</div>
diff --git a/polygerrit-ui/app/elements/admin/gr-group/gr-group.js b/polygerrit-ui/app/elements/admin/gr-group/gr-group.js
index 55bf3b0..9e0e8c6 100644
--- a/polygerrit-ui/app/elements/admin/gr-group/gr-group.js
+++ b/polygerrit-ui/app/elements/admin/gr-group/gr-group.js
@@ -56,11 +56,6 @@
type: Boolean,
value: true,
},
- _loggedIn: {
- type: Boolean,
- value: false,
- observer: '_loggedInChanged',
- },
/** @type {?} */
_groupConfig: Object,
_groupName: Object,
@@ -80,6 +75,10 @@
return this._getGroupSuggestions.bind(this);
},
},
+ _isAdmin: {
+ type: Boolean,
+ value: false,
+ },
},
observers: [
@@ -98,12 +97,22 @@
return this.$.restAPI.getGroupConfig(this.groupId).then(
config => {
- this._groupConfig = config;
this._groupName = config.name;
- this.fire('title-change', {title: config.name});
- this._loading = false;
+
+ this.$.restAPI.getIsAdmin().then(isAdmin => {
+ this._isAdmin = isAdmin ? true : false;
+ });
+
this.$.restAPI.getIsGroupOwner(config.name)
- .then(isOwner => { this._groupOwner = isOwner; });
+ .then(isOwner => {
+ this._groupOwner = isOwner ? true : false;
+ });
+
+ this._groupConfig = config;
+
+ this.fire('title-change', {title: config.name});
+
+ this._loading = false;
});
},
@@ -111,18 +120,10 @@
return loading ? 'loading' : '';
},
- _loggedInChanged(_loggedIn) {
- if (!_loggedIn) { return; }
- },
-
_isLoading() {
return this._loading || this._loading === undefined;
},
- _getLoggedIn() {
- return this.$.restAPI.getLoggedIn();
- },
-
_handleSaveName() {
return this.$.restAPI.saveGroupName(this.groupId, this._groupConfig.name)
.then(config => {
@@ -182,10 +183,6 @@
this._options = true;
},
- _computeButtonDisabled(options, option) {
- return !options || !option;
- },
-
_computeHeaderClass(configChanged) {
return configChanged ? 'edited' : '';
},
@@ -204,5 +201,9 @@
return groups;
});
},
+
+ _computeGroupDisabled(owner, admin) {
+ return admin || owner ? false : true;
+ },
});
})();
diff --git a/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.html b/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.html
index 75bd905..3c3b938 100644
--- a/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.html
@@ -121,5 +121,29 @@
done();
});
});
+
+ test('_computeGroupDisabled return false for admin', () => {
+ const admin = true;
+ const owner = false;
+ assert.equal(element._computeGroupDisabled(owner, admin), false);
+ });
+
+ test('_computeGroupDisabled return true for admin', () => {
+ const admin = false;
+ const owner = false;
+ assert.equal(element._computeGroupDisabled(owner, admin), true);
+ });
+
+ test('_computeGroupDisabled return false for owner', () => {
+ const admin = false;
+ const owner = true;
+ assert.equal(element._computeGroupDisabled(owner, admin), false);
+ });
+
+ test('_computeGroupDisabled return true for owner', () => {
+ const admin = false;
+ const owner = false;
+ assert.equal(element._computeGroupDisabled(owner, admin), true);
+ });
});
</script>
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js
index d5506ad..20fd147 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js
@@ -16,6 +16,13 @@
Polymer({
is: 'gr-label-score-row',
+
+ /**
+ * Fired when any label is changed.
+ *
+ * @event labels-changed
+ */
+
properties: {
/**
* @type {{ name: string }}
@@ -96,6 +103,7 @@
// nothing and then to the new item.
if (!e.target.selectedItem) { return; }
this._selectedValueText = e.target.selectedItem.getAttribute('title');
+ this.fire('labels-changed');
},
_computeAnyPermittedLabelValues(permittedLabels, label) {
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
index 537bd25..da450e1 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
@@ -103,6 +103,8 @@
});
test('label picker', () => {
+ const labelsChangedHandler = sandbox.stub();
+ element.addEventListener('labels-changed', labelsChangedHandler);
assert.ok(element.$$('iron-selector'));
MockInteractions.tap(element.$$(
'gr-button[value="-1"]'));
@@ -112,6 +114,7 @@
.textContent.trim(), '-1');
assert.strictEqual(
element.$.selectedValueLabel.textContent.trim(), 'bad');
+ assert.isTrue(labelsChangedHandler.called);
});
test('correct item is selected', () => {
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
index 2f9f78c..24673ff 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
@@ -241,6 +241,7 @@
id="labelScores"
account="[[_account]]"
change="[[change]]"
+ on-labels-changed="_handleLabelsChanged"
permitted-labels=[[permittedLabels]]></gr-label-scores>
</section>
<section class="draftsContainer" hidden$="[[_computeHideDraftList(diffDrafts)]]">
@@ -265,7 +266,7 @@
<section>
<gr-button
primary
- disabled="[[_isState(knownLatestState, 'not-latest')]]"
+ disabled="[[_computeSendButtonDisabled(knownLatestState, _sendButtonLabel, diffDrafts, draft, _reviewersMutated, _labelsChanged)]]"
class="action send"
on-tap="_sendTapHandler">[[_sendButtonLabel]]</gr-button>
<template is="dom-if" if="[[canBeStarted]]">
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
index 752f15a..9f4a79a 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
@@ -34,6 +34,11 @@
NOT_LATEST: 'not-latest',
};
+ const ButtonLabels = {
+ START_REVIEW: 'Start review',
+ SEND: 'Send',
+ };
+
// TODO(logan): Remove once the fix for issue 6841 is stable on
// googlesource.com.
const START_REVIEW_MESSAGE = 'This change is ready for review.';
@@ -175,6 +180,14 @@
computed: '_computeCCsEnabled(serverConfig)',
},
_savingComments: Boolean,
+ _reviewersMutated: {
+ type: Boolean,
+ value: false,
+ },
+ _labelsChanged: {
+ type: Boolean,
+ value: false,
+ },
},
FocusTarget,
@@ -268,12 +281,14 @@
_ccsChanged(splices) {
if (splices && splices.indexSplices) {
+ this._reviewersMutated = true;
this._processReviewerChange(splices.indexSplices, ReviewerTypes.CC);
}
},
_reviewersChanged(splices) {
if (splices && splices.indexSplices) {
+ this._reviewersMutated = true;
this._processReviewerChange(splices.indexSplices,
ReviewerTypes.REVIEWER);
let key;
@@ -768,6 +783,11 @@
});
},
+ _handleLabelsChanged() {
+ this._labelsChanged = Object.keys(
+ this.$.labelScores.getLabelValues()).length !== 0;
+ },
+
_isState(knownLatestState, value) {
return knownLatestState === value;
},
@@ -778,7 +798,7 @@
},
_computeSendButtonLabel(canBeStarted) {
- return canBeStarted ? 'Start review' : 'Send';
+ return canBeStarted ? ButtonLabels.START_REVIEW : ButtonLabels.SEND;
},
_computeCCsEnabled(serverConfig) {
@@ -788,5 +808,17 @@
_computeSavingLabelClass(savingComments) {
return savingComments ? 'saving' : '';
},
+
+ _computeSendButtonDisabled(knownLatestState, buttonLabel, drafts, text,
+ reviewersMutated, labelsChanged) {
+ if (this._isState(knownLatestState, LatestPatchState.NOT_LATEST)) {
+ return true;
+ }
+ if (buttonLabel === ButtonLabels.START_REVIEW) {
+ return false;
+ }
+ return !(drafts.length || text.length || reviewersMutated ||
+ labelsChanged);
+ },
});
})();
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
index 0f90019..9a83259 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
@@ -55,6 +55,8 @@
stub('gr-rest-api-interface', {
getConfig() { return Promise.resolve({}); },
getAccount() { return Promise.resolve({}); },
+ getChange() { return Promise.resolve({}); },
+ getChangeSuggestedReviewers() { return Promise.resolve([]); },
});
element = fixture('basic');
@@ -1007,5 +1009,20 @@
});
});
});
+
+ test('_computeSendButtonDisabled', () => {
+ const fn = element._computeSendButtonDisabled.bind(element);
+ assert.isTrue(fn('not-latest'));
+ assert.isFalse(fn('latest', 'Start review'));
+ assert.isTrue(fn('latest', 'Send', [], '', false, false));
+ // Mock nonempty comment draft array.
+ assert.isFalse(fn('latest', 'Send', ['test'], '', false, false));
+ // Mock nonempty change message.
+ assert.isFalse(fn('latest', 'Send', [], 'test', false, false));
+ // Mock reviewers mutated.
+ assert.isFalse(fn('latest', 'Send', [], '', true, false));
+ // Mock labels changed.
+ assert.isFalse(fn('latest', 'Send', [], '', false, true));
+ });
});
</script>
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index 93bddcb..3a724bb 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -447,7 +447,8 @@
this._mapRoute(RoutePattern.GROUP_AUDIT_LOG, '_handleGroupAuditLogRoute',
true);
- this._mapRoute(RoutePattern.GROUP_MEMBERS, '_handleGroupMembersRoute');
+ this._mapRoute(RoutePattern.GROUP_MEMBERS, '_handleGroupMembersRoute',
+ true);
this._mapRoute(RoutePattern.GROUP_LIST_OFFSET,
'_handleGroupListOffsetRoute', true);
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
index cb659f8..c294b22 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
@@ -133,6 +133,7 @@
'_handleGroupListFilterOffsetRoute',
'_handleGroupListFilterRoute',
'_handleGroupListOffsetRoute',
+ '_handleGroupMembersRoute',
'_handleGroupRoute',
'_handlePluginListFilterOffsetRoute',
'_handlePluginListFilterRoute',
@@ -153,7 +154,6 @@
'_handleDefaultRoute',
'_handleChangeLegacyRoute',
'_handleDiffLegacyRoute',
- '_handleGroupMembersRoute',
'_handleImproperlyEncodedPlusRoute',
'_handlePassThroughRoute',
'_handleProjectAccessRoute',
diff --git a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.html b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.html
index c93ed0c..43343de 100644
--- a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.html
+++ b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.html
@@ -49,6 +49,17 @@
</tr>
</thead>
<tbody>
+ <tr>
+ <td>Number</td>
+ <td
+ class="checkboxContainer"
+ on-tap="_handleTargetTap">
+ <input
+ type="checkbox"
+ name="number"
+ checked$="[[showNumber]]">
+ </td>
+ </tr>
<template is="dom-repeat" items="[[columnNames]]">
<tr>
<td>[[item]]</td>
diff --git a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.js b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.js
index 50a1146..4d87f9e 100644
--- a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.js
+++ b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.js
@@ -22,6 +22,10 @@
type: Array,
notify: true,
},
+ showNumber: {
+ type: Boolean,
+ notify: true,
+ },
},
behaviors: [
@@ -53,6 +57,12 @@
// The target is the checkbox itself.
checkbox = Polymer.dom(e).rootTarget;
}
+
+ if (checkbox.name === 'number') {
+ this.showNumber = checkbox.checked;
+ return;
+ }
+
this.set('displayedColumns',
this._updateDisplayedColumns(
this.displayedColumns, checkbox.name, checkbox.checked));
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 61093b9..00ef16f 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
@@ -62,15 +62,17 @@
const rows = element.$$('tbody').querySelectorAll('tr');
let tds;
- assert.equal(rows.length, element.columnNames.length);
+ // The `+ 1` is for the number column, which isn't included in the change
+ // table behavior's list.
+ assert.equal(rows.length, element.columnNames.length + 1);
for (let i = 0; i < columns.length; i++) {
- tds = rows[i].querySelectorAll('td');
+ tds = rows[i + 1].querySelectorAll('td');
assert.equal(tds[0].textContent, columns[i]);
}
});
test('hide item', () => {
- const checkbox = element.$$('table input');
+ const checkbox = element.$$('table tr:nth-child(2) input');
const isChecked = checkbox.checked;
const displayedLength = element.displayedColumns.length;
assert.isTrue(isChecked);
@@ -78,8 +80,7 @@
MockInteractions.tap(checkbox);
flushAsynchronousOperations();
- assert.equal(element.displayedColumns.length,
- displayedLength - 1);
+ assert.equal(element.displayedColumns.length, displayedLength - 1);
});
test('show item', () => {
@@ -91,7 +92,7 @@
'Updated',
]);
flushAsynchronousOperations();
- const checkbox = element.$$('table input');
+ const checkbox = element.$$('table tr:nth-child(2) input');
const isChecked = checkbox.checked;
const displayedLength = element.displayedColumns.length;
assert.isFalse(isChecked);
@@ -105,9 +106,9 @@
});
test('_handleTargetTap', () => {
- const checkbox = element.$$('table input');
+ const checkbox = element.$$('table tr:nth-child(2) input');
let originalDisplayedColumns = element.displayedColumns;
- const td = element.$$('table .checkboxContainer');
+ const td = element.$$('table tr:nth-child(2) .checkboxContainer');
const displayedColumnStub =
sandbox.stub(element, '_updateDisplayedColumns');
@@ -125,6 +126,20 @@
checkbox.checked));
});
+ test('_handleTargetTap on number', () => {
+ element.showNumber = false;
+ const checkbox = element.$$('table tr:nth-child(1) input');
+ const displayedColumnStub =
+ sandbox.stub(element, '_updateDisplayedColumns');
+
+ MockInteractions.tap(checkbox);
+ assert.isFalse(displayedColumnStub.called);
+ assert.isTrue(element.showNumber);
+
+ MockInteractions.tap(checkbox);
+ assert.isFalse(element.showNumber);
+ });
+
test('_updateDisplayedColumns', () => {
let name = 'Subject';
let checked = false;
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
index d039a3b..cacccda 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
@@ -321,6 +321,7 @@
</h2>
<fieldset id="changeTableColumns">
<gr-change-table-editor
+ show-number="{{_showNumber}}"
displayed-columns="{{_localChangeTableColumns}}">
</gr-change-table-editor>
<gr-button
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
index c3332b3..25dd259 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
@@ -121,6 +121,8 @@
* For testing purposes.
*/
_loadingPromise: Object,
+
+ _showNumber: Boolean,
},
behaviors: [
@@ -132,7 +134,7 @@
'_handlePrefsChanged(_localPrefs.*)',
'_handleDiffPrefsChanged(_diffPrefs.*)',
'_handleMenuChanged(_localMenu.splices)',
- '_handleChangeTableChanged(_localChangeTableColumns)',
+ '_handleChangeTableChanged(_localChangeTableColumns, _showNumber)',
],
attached() {
@@ -147,6 +149,7 @@
promises.push(this.$.restAPI.getPreferences().then(prefs => {
this.prefs = prefs;
+ this._showNumber = !!prefs.legacycid_in_change_table;
this._copyPrefs('_localPrefs', 'prefs');
this._cloneMenu();
this._cloneChangeTableColumns();
@@ -303,6 +306,7 @@
_handleSaveChangeTable() {
this.set('prefs.change_table', this._localChangeTableColumns);
+ this.set('prefs.legacycid_in_change_table', this._showNumber);
this._cloneChangeTableColumns();
return this.$.restAPI.savePreferences(this.prefs).then(() => {
this._changeTableChanged = false;
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
index e1182c1..868a9e3 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
@@ -386,6 +386,25 @@
assert.isTrue(element.$.emailEditor.loadData.calledOnce);
});
+ test('_handleSaveChangeTable', () => {
+ let newColumns = ['Owner', 'Project', 'Branch'];
+ element._localChangeTableColumns = newColumns.slice(0);
+ element._showNumber = false;
+ const cloneStub = sandbox.stub(element, '_cloneChangeTableColumns');
+ element._handleSaveChangeTable();
+ assert.isTrue(cloneStub.calledOnce);
+ assert.deepEqual(element.prefs.change_table, newColumns);
+ assert.isNotOk(element.prefs.legacycid_in_change_table);
+
+ newColumns = ['Size'];
+ element._localChangeTableColumns = newColumns;
+ element._showNumber = true;
+ element._handleSaveChangeTable();
+ assert.isTrue(cloneStub.calledTwice);
+ assert.deepEqual(element.prefs.change_table, newColumns);
+ assert.isTrue(element.prefs.legacycid_in_change_table);
+ });
+
suite('_getFilterDocsLink', () => {
test('with http: docs base URL', () => {
const base = 'http://example.com/';
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 a016037..06a3fcf 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
@@ -274,7 +274,7 @@
getGroupConfig(group) {
const encodeName = encodeURIComponent(group);
- return this._fetchSharedCacheURL('/groups/' + encodeName + '/detail');
+ return this.fetchJSON(`/groups/${encodeName}/detail`);
},
/**
@@ -348,8 +348,8 @@
*/
getIsGroupOwner(groupName) {
const encodeName = encodeURIComponent(groupName);
- return this._fetchSharedCacheURL('/groups/?owned&q=' + encodeName)
- .then(configs => configs.hasOwnProperty(encodeName));
+ return this._fetchSharedCacheURL(`/groups/?owned&q=${encodeName}`)
+ .then(configs => configs.hasOwnProperty(groupName));
},
getGroupMembers(groupName) {
@@ -1645,7 +1645,7 @@
setChangeTopic(changeNum, topic) {
const p = {topic};
return this.getChangeURLAndSend(changeNum, 'PUT', null, '/topic', p)
- .then(this.getResponseObject);
+ .then(this.getResponseObject.bind(this));
},
/**
@@ -1655,7 +1655,7 @@
*/
setChangeHashtag(changeNum, hashtag) {
return this.getChangeURLAndSend(changeNum, 'POST', null, '/hashtags',
- hashtag).then(this.getResponseObject);
+ hashtag).then(this.getResponseObject.bind(this));
},
deleteAccountHttpPassword() {
@@ -1669,7 +1669,7 @@
*/
generateAccountHttpPassword() {
return this.send('PUT', '/accounts/self/password.http', {generate: true})
- .then(this.getResponseObject);
+ .then(this.getResponseObject.bind(this));
},
getAccountSSHKeys() {
@@ -1772,7 +1772,7 @@
const endpoint = `/comments/${commentID}/delete`;
const payload = {reason};
return this.getChangeURLAndSend(changeNum, 'POST', patchNum, endpoint,
- payload).then(this.getResponseObject);
+ payload).then(this.getResponseObject.bind(this));
},
/**
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 3f47ea8..eb4f418 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
@@ -958,5 +958,29 @@
assert.deepEqual(result, obj);
});
});
+
+ test('setChangeTopic', () => {
+ const sendSpy = sandbox.spy(element, 'getChangeURLAndSend');
+ return element.setChangeTopic(123, 'foo-bar').then(() => {
+ assert.isTrue(sendSpy.calledOnce);
+ assert.deepEqual(sendSpy.lastCall.args[4], {topic: 'foo-bar'});
+ });
+ });
+
+ test('setChangeHashtag', () => {
+ const sendSpy = sandbox.spy(element, 'getChangeURLAndSend');
+ return element.setChangeHashtag(123, 'foo-bar').then(() => {
+ assert.isTrue(sendSpy.calledOnce);
+ assert.equal(sendSpy.lastCall.args[4], 'foo-bar');
+ });
+ });
+
+ test('generateAccountHttpPassword', () => {
+ const sendSpy = sandbox.spy(element, 'send');
+ return element.generateAccountHttpPassword().then(() => {
+ assert.isTrue(sendSpy.calledOnce);
+ assert.deepEqual(sendSpy.lastCall.args[2], {generate: true});
+ });
+ });
});
</script>