Merge "Add username to registration dialog"
This commit is contained in:
@@ -372,6 +372,10 @@ limitations under the License.
|
||||
detail: Gerrit.Nav.GroupDetailView.MEMBERS,
|
||||
});
|
||||
},
|
||||
|
||||
getUrlForSettings() {
|
||||
return this._getUrlFor({view: Gerrit.Nav.View.SETTINGS});
|
||||
},
|
||||
};
|
||||
})(window);
|
||||
</script>
|
||||
|
@@ -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
|
||||
|
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../../styles/gr-form-styles.html">
|
||||
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
|
||||
<link rel="import" href="../../shared/gr-button/gr-button.html">
|
||||
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
<link rel="import" href="../../../styles/shared-styles.html">
|
||||
@@ -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;
|
||||
}
|
||||
</style>
|
||||
<main class="gr-form-styles">
|
||||
<div class="container gr-form-styles">
|
||||
<header>Please confirm your contact information</header>
|
||||
<main>
|
||||
<p>
|
||||
@@ -64,8 +70,15 @@ limitations under the License.
|
||||
is="iron-input"
|
||||
id="name"
|
||||
bind-value="{{_account.name}}"
|
||||
disabled="[[_saving]]"
|
||||
on-keydown="_handleNameKeydown">
|
||||
disabled="[[_saving]]">
|
||||
</section>
|
||||
<section>
|
||||
<div class="title">Username</div>
|
||||
<input
|
||||
is="iron-input"
|
||||
id="username"
|
||||
bind-value="{{_account.username}}"
|
||||
disabled="[[_saving]]">
|
||||
</section>
|
||||
<section>
|
||||
<div class="title">Preferred Email</div>
|
||||
@@ -78,19 +91,26 @@ limitations under the License.
|
||||
</template>
|
||||
</select>
|
||||
</section>
|
||||
<hr>
|
||||
<p>
|
||||
More configuration options for Gerrit may be found in the
|
||||
<a on-tap="close" href$="[[_computeSettingsUrl(_account)]]">settings</a>.
|
||||
</p>
|
||||
</main>
|
||||
<footer>
|
||||
<gr-button
|
||||
id="saveButton"
|
||||
primary
|
||||
disabled="[[_saving]]"
|
||||
on-tap="_handleSave">Save</gr-button>
|
||||
<gr-button
|
||||
id="closeButton"
|
||||
link
|
||||
disabled="[[_saving]]"
|
||||
on-tap="_handleClose">Close</gr-button>
|
||||
<gr-button
|
||||
id="saveButton"
|
||||
primary
|
||||
link
|
||||
disabled="[[_computeSaveDisabled(_account.name, _account.username, _account.email, _saving)]]"
|
||||
on-tap="_handleSave">Save</gr-button>
|
||||
</footer>
|
||||
</main>
|
||||
</div>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
</template>
|
||||
<script src="gr-registration-dialog.js"></script>
|
||||
|
@@ -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();
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
@@ -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));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
Reference in New Issue
Block a user