diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html index a935e269d2..0de15804b7 100644 --- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html +++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html @@ -372,6 +372,10 @@ limitations under the License. detail: Gerrit.Nav.GroupDetailView.MEMBERS, }); }, + + getUrlForSettings() { + return this._getUrlFor({view: Gerrit.Nav.View.SETTINGS}); + }, }; })(window); 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 8bc2a0b87f..c31855a21b 100644 --- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js +++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js @@ -228,6 +228,8 @@ url = this._generateDiffOrEditUrl(params); } else if (params.view === Views.GROUP) { url = this._generateGroupUrl(params); + } else if (params.view === Views.SETTINGS) { + url = this._generateSettingsUrl(params); } else { throw new Error('Can\'t generate'); } @@ -351,6 +353,14 @@ return url; }, + /** + * @param {!Object} params + * @return {string} + */ + _generateSettingsUrl(params) { + return '/settings'; + }, + /** * Given an object of parameters, potentially including a `patchNum` or a * `basePatchNum` or both, return a string representation of that range. If diff --git a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html index de6783de99..0cbd1f6301 100644 --- a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html +++ b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html @@ -16,6 +16,7 @@ limitations under the License. + @@ -37,18 +38,23 @@ limitations under the License. header { border-bottom: 1px solid #cdcdcd; font-family: var(--font-family-bold); + margin-bottom: 1em; } - header, - main, - footer { + .container { padding: .5em 1.5em; } footer { display: flex; - justify-content: space-between; + justify-content: flex-end; + } + footer gr-button { + margin-left: 1em; + } + input { + width: 20em; } -
+
Please confirm your contact information

@@ -64,8 +70,15 @@ limitations under the License. is="iron-input" id="name" bind-value="{{_account.name}}" - disabled="[[_saving]]" - on-keydown="_handleNameKeydown"> + disabled="[[_saving]]"> + +

+
Username
+
Preferred Email
@@ -78,19 +91,26 @@ limitations under the License.
+
+

+ More configuration options for Gerrit may be found in the + settings. +

-
+ diff --git a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.js b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.js index 71d80eb377..406d16c104 100644 --- a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.js +++ b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.js @@ -31,8 +31,18 @@ properties: { /** @type {?} */ - _account: Object, - _saving: Boolean, + _account: { + type: Object, + value: () => { + // Prepopulate possibly undefined fields with values to trigger + // computed bindings. + return {email: null, name: null, username: null}; + }, + }, + _saving: { + type: Boolean, + value: false, + }, }, hostAttributes: { @@ -41,22 +51,19 @@ attached() { this.$.restAPI.getAccount().then(account => { - this._account = account; + // Using Object.assign here allows preservation of the default values + // supplied in the value generating function of this._account, unless + // they are overridden by properties in the account from the response. + this._account = Object.assign({}, this._account, account); }); }, - _handleNameKeydown(e) { - if (e.keyCode === 13) { // Enter - e.stopPropagation(); - this._save(); - } - }, - _save() { this._saving = true; const promises = [ this.$.restAPI.setAccountName(this.$.name.value), - this.$.restAPI.setPreferredAccountEmail(this.$.email.value), + this.$.restAPI.setAccountUsername(this.$.username.value), + this.$.restAPI.setPreferredAccountEmail(this.$.email.value || ''), ]; return Promise.all(promises).then(() => { this._saving = false; @@ -66,15 +73,25 @@ _handleSave(e) { e.preventDefault(); - this._save().then(() => { - this.fire('close'); - }); + this._save().then(this.close.bind(this)); }, _handleClose(e) { e.preventDefault(); + this.close(); + }, + + close() { this._saving = true; // disable buttons indefinitely this.fire('close'); }, + + _computeSaveDisabled(name, username, email, saving) { + return !name || !username || !email || saving; + }, + + _computeSettingsUrl() { + return Gerrit.Nav.getUrlForSettings(); + }, }); })(); diff --git a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html index 858c3ae3b0..15b4fa2f2a 100644 --- a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html +++ b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html @@ -41,13 +41,16 @@ limitations under the License. suite('gr-registration-dialog tests', () => { let element; let account; + let sandbox; let _listeners; setup(done => { + sandbox = sinon.sandbox.create(); _listeners = {}; account = { name: 'name', + username: 'username', email: 'email', secondary_emails: [ 'email2', @@ -65,6 +68,10 @@ limitations under the License. account.name = name; return Promise.resolve(); }, + setAccountUsername(username) { + account.username = username; + return Promise.resolve(); + }, setPreferredAccountEmail(email) { account.email = email; return Promise.resolve(); @@ -75,6 +82,7 @@ limitations under the License. }); teardown(() => { + sandbox.restore(); for (const eventType in _listeners) { if (_listeners.hasOwnProperty(eventType)) { element.removeEventListener(eventType, _listeners[eventType]); @@ -119,32 +127,26 @@ limitations under the License. }).then(done); }); - test('saves name and preferred email', done => { + test('saves account details', done => { flush(() => { element.$.name.value = 'new name'; + element.$.username.value = 'new username'; element.$.email.value = 'email3'; // Nothing should be committed yet. assert.equal(account.name, 'name'); + assert.equal(account.username, 'username'); assert.equal(account.email, 'email'); // Save and verify new values are committed. save().then(() => { assert.equal(account.name, 'new name'); + assert.equal(account.username, 'new username'); assert.equal(account.email, 'email3'); }).then(done); }); }); - test('pressing enter saves name', done => { - element.$.name.value = 'entered name'; - save(() => { - MockInteractions.pressAndReleaseKeyOn(element.$.name, 13); // 'enter' - }).then(() => { - assert.equal(account.name, 'entered name'); - }).then(done); - }); - test('email select properly populated', done => { element._account = {email: 'foo', secondary_emails: ['bar', 'baz']}; flush(() => { @@ -152,5 +154,15 @@ limitations under the License. done(); }); }); + + test('save btn disabled', () => { + const compute = element._computeSaveDisabled; + assert.isTrue(compute('', '', '', false)); + assert.isTrue(compute('', 'test', 'test', false)); + assert.isTrue(compute('test', '', 'test', false)); + assert.isTrue(compute('test', 'test', '', false)); + assert.isTrue(compute('test', 'test', 'test', true)); + assert.isFalse(compute('test', 'test', 'test', false)); + }); });