diff --git a/app/assets/javascripts/wizard/components/invite-list-user.js.es6 b/app/assets/javascripts/wizard/components/invite-list-user.js.es6
new file mode 100644
index 000000000..c54290fb8
--- /dev/null
+++ b/app/assets/javascripts/wizard/components/invite-list-user.js.es6
@@ -0,0 +1,16 @@
+import computed from 'ember-addons/ember-computed-decorators';
+
+export default Ember.Component.extend({
+ classNames: ['invite-list-user'],
+
+ @computed('user.role')
+ roleName(role) {
+ return this.get('roles').findProperty('id', role).label;
+ },
+
+ actions: {
+ removeUser(user) {
+ this.sendAction('removeUser', user);
+ }
+ }
+});
diff --git a/app/assets/javascripts/wizard/components/invite-list.js.es6 b/app/assets/javascripts/wizard/components/invite-list.js.es6
new file mode 100644
index 000000000..2083c41db
--- /dev/null
+++ b/app/assets/javascripts/wizard/components/invite-list.js.es6
@@ -0,0 +1,62 @@
+export default Ember.Component.extend({
+ classNames: ['invite-list'],
+ users: null,
+ inviteEmail: '',
+ inviteRole: '',
+ invalid: false,
+
+ init() {
+ this._super();
+ this.set('users', []);
+
+ this.set('roles', [
+ {id: 'moderator', label: I18n.t('wizard.invites.roles.moderator') },
+ {id: 'regular', label: I18n.t('wizard.invites.roles.regular') },
+ ]);
+
+ this.updateField();
+ },
+
+ keyPress(e) {
+ if (e.keyCode === 13) {
+ e.preventDefault();
+ e.stopPropagation();
+ this.send('addUser');
+ }
+ },
+
+ updateField() {
+ this.set('field.value', JSON.stringify(this.get('users')));
+ },
+
+ actions: {
+ addUser() {
+ const user = {
+ email: this.get('inviteEmail') || '',
+ role: this.get('inviteRole')
+ };
+
+ if (!/(.+)@(.+){2,}\.(.+){2,}/.test(user.email)) {
+ return this.set('invalid', true);
+ }
+
+ const users = this.get('users');
+ if (users.findProperty('email', user.email)) {
+ return this.set('invalid', true);
+ }
+
+ this.set('invalid', false);
+
+ users.pushObject(user);
+ this.updateField();
+
+ this.set('inviteEmail', '');
+ Ember.run.scheduleOnce('afterRender', () => this.$('.invite-email').focus());
+ },
+
+ removeUser(user) {
+ this.get('users').removeObject(user);
+ this.updateField();
+ }
+ }
+});
diff --git a/app/assets/javascripts/wizard/templates/components/invite-list-user.hbs b/app/assets/javascripts/wizard/templates/components/invite-list-user.hbs
new file mode 100644
index 000000000..b957827ad
--- /dev/null
+++ b/app/assets/javascripts/wizard/templates/components/invite-list-user.hbs
@@ -0,0 +1,6 @@
+{{user.email}}
+{{roleName}}
+
+
diff --git a/app/assets/javascripts/wizard/templates/components/invite-list.hbs b/app/assets/javascripts/wizard/templates/components/invite-list.hbs
new file mode 100644
index 000000000..fb0299b70
--- /dev/null
+++ b/app/assets/javascripts/wizard/templates/components/invite-list.hbs
@@ -0,0 +1,20 @@
+
+{{#if users}}
+
+ {{#each users as |user|}}
+ {{invite-list-user user=user roles=roles removeUser="removeUser"}}
+ {{/each}}
+
+{{/if}}
+
+
+
+ {{input class="invite-email" value=inviteEmail placeholder="user@example.com"}}
+
+
+ {{combo-box value=inviteRole content=roles nameProperty="label" width="200px"}}
+
+
+
diff --git a/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs b/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs
index e993ecb95..6be3fc1a8 100644
--- a/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs
+++ b/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs
@@ -1 +1,6 @@
-{{combo-box class=fieldClass value=field.value content=field.choices nameProperty="label" width="400px"}}
+{{combo-box elementId=field.id
+ class=fieldClass
+ value=field.value
+ content=field.choices
+ nameProperty="label"
+ width="400px"}}
diff --git a/app/assets/javascripts/wizard/templates/components/wizard-field-text.hbs b/app/assets/javascripts/wizard/templates/components/wizard-field-text.hbs
index 2a0770e89..0a5d877a8 100644
--- a/app/assets/javascripts/wizard/templates/components/wizard-field-text.hbs
+++ b/app/assets/javascripts/wizard/templates/components/wizard-field-text.hbs
@@ -1 +1 @@
-{{input value=field.value class=fieldClass placeholder=field.placeholder}}
+{{input elementId=field.id value=field.value class=fieldClass placeholder=field.placeholder}}
diff --git a/app/assets/javascripts/wizard/templates/components/wizard-field.hbs b/app/assets/javascripts/wizard/templates/components/wizard-field.hbs
index 21f76b269..980ed2967 100644
--- a/app/assets/javascripts/wizard/templates/components/wizard-field.hbs
+++ b/app/assets/javascripts/wizard/templates/components/wizard-field.hbs
@@ -1,16 +1,15 @@
-