register: Update the user-registration form for realm creation.

In previous commits, we updated the realm creation flow to show
the realm name, type and subdomain fields in the first form
when asking for the email of the user. This commit updates the
user registration form to show the already filled realm details
as non-editable text and there is also a button to edit the
realm details before registration.

We also update the sub-heading for user registration form as
mentioned in the issue.

Fixes part of #24307.
This commit is contained in:
Sahil Batra 2023-03-09 17:00:03 +05:30 committed by Tim Abbott
parent c225de789e
commit cf8d8db132
9 changed files with 149 additions and 79 deletions

View File

@ -1,3 +1,4 @@
<div class="realm-creation-editable-inputs {% if user_registration_form and not form.realm_subdomain.errors %}hide{% endif %}">
<div class="input-box"> <div class="input-box">
<div class="inline-block relative"> <div class="inline-block relative">
<input id="id_team_name" class="required" type="text" <input id="id_team_name" class="required" type="text"
@ -12,9 +13,11 @@
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if not user_registration_form %}
<div class="help-text"> <div class="help-text">
{{ _('Shorter is better than longer.') }} {{ _('Shorter is better than longer.') }}
</div> </div>
{% endif %}
</div> </div>
<div class="input-box"> <div class="input-box">
@ -22,7 +25,7 @@
<select name="realm_type" id="realm_type"> <select name="realm_type" id="realm_type">
{% for realm_type in sorted_realm_types %} {% for realm_type in sorted_realm_types %}
{% if not realm_type.hidden %} {% if not realm_type.hidden %}
<option value="{{ realm_type.id }}">{{ _(realm_type.name) }}</option> <option value="{{ realm_type.id }}" {% if form.realm_type.value() == realm_type.id %}selected{% endif %} >{{ _(realm_type.name) }}</option>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</select> </select>
@ -64,3 +67,4 @@
{% endif %} {% endif %}
</div> </div>
</div> </div>
</div>

View File

@ -24,7 +24,7 @@ Form is validated both client-side using jquery-validation (see signup.js) and s
{% endif %} {% endif %}
{% trans %} {% trans %}
<p>You&rsquo;re almost there! We just need you to do one last thing.</p> <p>Enter your account details to complete registration.</p>
{% endtrans %} {% endtrans %}
</div> </div>
@ -33,11 +33,31 @@ Form is validated both client-side using jquery-validation (see signup.js) and s
<fieldset class="org-registration"> <fieldset class="org-registration">
{% if creating_new_realm %} {% if creating_new_realm %}
<legend>{{ _('Your organization') }}</legend> <legend>{{ _('Your organization') }}
{% if not form.realm_subdomain.errors %}
<span class="edit-realm-details" role="button" tabindex="0"><i class="fa fa-pencil"></i></span>
{% endif %}
</legend>
{% with %} {% with %}
{% set user_registration_form = "true" %} {% set user_registration_form = "true" %}
{% include 'zerver/realm_creation_form.html' %} {% include 'zerver/realm_creation_form.html' %}
{% endwith %} {% endwith %}
{% if not form.realm_subdomain.errors %}
<div class="not-editable-realm-details">
<div class="input-box">
<label for="id_realm_name" class="inline-block label-title">{{ _('Organization name') }}</label>
<div id="id_realm_name" class="not-editable-realm-field">{{ form.realm_name.value() }}</div>
</div>
<div class="input-box">
<label for="id_realm_type" class="inline-block label-title">{{ _('Organization type') }}</label>
<div id="id_realm_type" class="not-editable-realm-field">{{ selected_realm_type_name }}</div>
</div>
<div class="input-box">
<label for="id_realm_subdomain" class="inline-block label-title">{{ _('Organization URL') }}</label>
<div id="id_realm_subdomain" class="not-editable-realm-field">{% if form.realm_subdomain.value() %}{{ form.realm_subdomain.value() }}.{% endif %}{{external_host}}</div>
</div>
</div>
{% endif %}
{% endif %} {% endif %}
</fieldset> </fieldset>

View File

@ -48,7 +48,7 @@ async function realm_creation_tests(page: Page): Promise<void> {
const text_in_pitch = await page.evaluate( const text_in_pitch = await page.evaluate(
() => document.querySelector(".pitch p")!.textContent, () => document.querySelector(".pitch p")!.textContent,
); );
assert.equal(text_in_pitch, "Youre almost there! We just need you to do one last thing."); assert.equal(text_in_pitch, "Enter your account details to complete registration.");
// fill the form. // fill the form.
const params = { const params = {

View File

@ -284,4 +284,19 @@ $(() => {
} }
$("#new-user-email-address-visibility .current-selected-option").text(selected_option_text); $("#new-user-email-address-visibility .current-selected-option").text(selected_option_text);
}); });
$("#registration").on("click keypress", ".edit-realm-details", (e) => {
if (e.type === "keypress" && e.key !== "Enter") {
return;
}
$("#registration .not-editable-realm-details").addClass("hide");
$("#registration .realm-creation-editable-inputs").removeClass("hide");
$("#id_team_name").trigger("focus");
// This is a hack to have cursor at end after focussing the input.
const name_val = $("#id_team_name").val();
$("#id_team_name").val("").val(name_val);
$(e.target).hide();
});
}); });

View File

@ -1010,7 +1010,8 @@ button#register_auth_button_gitlab {
#id_email, #id_email,
#support_from, #support_from,
#support_realm { #support_realm,
.not-editable-realm-field {
font-weight: normal; font-weight: normal;
margin: 2px; margin: 2px;
padding-top: 25px; padding-top: 25px;
@ -1047,6 +1048,11 @@ button#register_auth_button_gitlab {
+ .input-box { + .input-box {
margin-top: 20px; margin-top: 20px;
} }
.edit-realm-details {
float: right;
cursor: pointer;
}
} }
.center-block .pitch { .center-block .pitch {

View File

@ -1409,7 +1409,7 @@ class SocialAuthBase(DesktopFlowTestingLib, ZulipTestCase, ABC):
confirmation_data = {"from_confirmation": "1", "key": confirmation_key} confirmation_data = {"from_confirmation": "1", "key": confirmation_key}
result = self.client_post("/accounts/register/", confirmation_data) result = self.client_post("/accounts/register/", confirmation_data)
if not skip_registration_form: if not skip_registration_form:
self.assert_in_response("We just need you to do one last thing", result) self.assert_in_response("Enter your account details to complete registration.", result)
# Verify that the user is asked for name but not password # Verify that the user is asked for name but not password
self.assert_not_in_success_response(["id_password"], result) self.assert_not_in_success_response(["id_password"], result)
@ -4282,7 +4282,7 @@ class GoogleAuthBackendTest(SocialAuthBase):
"key": confirmation_key, "key": confirmation_key,
} }
result = self.client_post("/accounts/register/", confirmation_data, subdomain="zulip") result = self.client_post("/accounts/register/", confirmation_data, subdomain="zulip")
self.assert_in_response("We just need you to do one last thing", result) self.assert_in_response("Enter your account details to complete registration.", result)
# Verify that the user is asked for name but not password # Verify that the user is asked for name but not password
self.assert_not_in_success_response(["id_password"], result) self.assert_not_in_success_response(["id_password"], result)
@ -4318,7 +4318,7 @@ class GoogleAuthBackendTest(SocialAuthBase):
"key": confirmation_key, "key": confirmation_key,
} }
result = self.client_post("/accounts/register/", confirmation_data, subdomain="zulip") result = self.client_post("/accounts/register/", confirmation_data, subdomain="zulip")
self.assert_in_response("We just need you to do one last thing", result) self.assert_in_response("Enter your account details to complete registration.", result)
# Verify that the user is asked for name but not password # Verify that the user is asked for name but not password
self.assert_not_in_success_response(["id_password"], result) self.assert_not_in_success_response(["id_password"], result)
@ -4372,7 +4372,7 @@ class GoogleAuthBackendTest(SocialAuthBase):
self.assert_in_response('action="/accounts/register/"', result) self.assert_in_response('action="/accounts/register/"', result)
data2 = {"from_confirmation": "1", "full_name": data["full_name"], "key": confirmation_key} data2 = {"from_confirmation": "1", "full_name": data["full_name"], "key": confirmation_key}
result = self.client_post("/accounts/register/", data2, subdomain="zulip") result = self.client_post("/accounts/register/", data2, subdomain="zulip")
self.assert_in_response("We just need you to do one last thing", result) self.assert_in_response("Enter your account details to complete registration.", result)
# Verify that the user is asked for name but not password # Verify that the user is asked for name but not password
self.assert_not_in_success_response(["id_password"], result) self.assert_not_in_success_response(["id_password"], result)

View File

@ -1436,7 +1436,9 @@ so we didn't send them an invitation. We did send invitations to everyone else!"
response = self.client_post( response = self.client_post(
url, {"key": registration_key, "from_confirmation": 1, "full_name": "alice"} url, {"key": registration_key, "from_confirmation": 1, "full_name": "alice"}
) )
self.assert_in_success_response(["We just need you to do one last thing."], response) self.assert_in_success_response(
["Enter your account details to complete registration."], response
)
response = self.submit_reg_form_for_user(email, password, key=registration_key) response = self.submit_reg_form_for_user(email, password, key=registration_key)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)

View File

@ -2431,7 +2431,9 @@ class UserSignUpTest(ZulipTestCase):
result = self.verify_signup(email=email, password=password, full_name="") result = self.verify_signup(email=email, password=password, full_name="")
# _WSGIPatchedWSGIResponse does not exist in Django, thus the inverted isinstance check. # _WSGIPatchedWSGIResponse does not exist in Django, thus the inverted isinstance check.
assert not isinstance(result, UserProfile) assert not isinstance(result, UserProfile)
self.assert_in_success_response(["We just need you to do one last thing."], result) self.assert_in_success_response(
["Enter your account details to complete registration."], result
)
# Verify that the user is asked for name and password # Verify that the user is asked for name and password
self.assert_in_success_response(["id_password", "id_full_name"], result) self.assert_in_success_response(["id_password", "id_full_name"], result)
@ -2486,7 +2488,9 @@ class UserSignUpTest(ZulipTestCase):
"from_confirmation": "1", "from_confirmation": "1",
}, },
) )
self.assert_in_success_response(["We just need you to do one last thing."], result) self.assert_in_success_response(
["Enter your account details to complete registration."], result
)
def test_signup_with_weak_password(self) -> None: def test_signup_with_weak_password(self) -> None:
""" """
@ -2521,7 +2525,9 @@ class UserSignUpTest(ZulipTestCase):
"from_confirmation": "1", "from_confirmation": "1",
}, },
) )
self.assert_in_success_response(["We just need you to do one last thing."], result) self.assert_in_success_response(
["Enter your account details to complete registration."], result
)
result = self.submit_reg_form_for_user(email, "easy", full_name="New Guy") result = self.submit_reg_form_for_user(email, "easy", full_name="New Guy")
self.assert_in_success_response(["The password is too weak."], result) self.assert_in_success_response(["The password is too weak."], result)
@ -2588,7 +2594,7 @@ class UserSignUpTest(ZulipTestCase):
email, password, full_name="New Guy", from_confirmation="1" email, password, full_name="New Guy", from_confirmation="1"
) )
self.assert_in_success_response( self.assert_in_success_response(
["We just need you to do one last thing.", "New Guy", email], result ["Enter your account details to complete registration.", "New Guy", email], result
) )
result = self.submit_reg_form_for_user(email, password, full_name="New Guy") result = self.submit_reg_form_for_user(email, password, full_name="New Guy")
user_profile = UserProfile.objects.get(delivery_email=email) user_profile = UserProfile.objects.get(delivery_email=email)
@ -2733,7 +2739,7 @@ class UserSignUpTest(ZulipTestCase):
[ [
"Import settings from existing Zulip account", "Import settings from existing Zulip account",
"selected >\n Zulip Dev", "selected >\n Zulip Dev",
"We just need you to do one last thing.", "Enter your account details to complete registration.",
], ],
result, result,
) )
@ -3007,7 +3013,7 @@ class UserSignUpTest(ZulipTestCase):
self.assert_in_success_response( self.assert_in_success_response(
[ [
"We just need you to do one last thing.", "Enter your account details to complete registration.",
"New LDAP fullname", "New LDAP fullname",
"newuser@zulip.com", "newuser@zulip.com",
], ],
@ -3034,7 +3040,8 @@ class UserSignUpTest(ZulipTestCase):
HTTP_HOST=subdomain + ".testserver", HTTP_HOST=subdomain + ".testserver",
) )
self.assert_in_success_response( self.assert_in_success_response(
["We just need you to do one last thing.", "newuser@zulip.com"], result ["Enter your account details to complete registration.", "newuser@zulip.com"],
result,
) )
@override_settings( @override_settings(
@ -3096,7 +3103,7 @@ class UserSignUpTest(ZulipTestCase):
self.assert_in_success_response( self.assert_in_success_response(
[ [
"We just need you to do one last thing.", "Enter your account details to complete registration.",
"New LDAP fullname", "New LDAP fullname",
"newuser@zulip.com", "newuser@zulip.com",
], ],
@ -3159,7 +3166,12 @@ class UserSignUpTest(ZulipTestCase):
# Full name should be set from LDAP # Full name should be set from LDAP
self.assert_in_success_response( self.assert_in_success_response(
["We just need you to do one last thing.", full_name, "newuser@zulip.com"], result [
"Enter your account details to complete registration.",
full_name,
"newuser@zulip.com",
],
result,
) )
# Submit the final form with the wrong password. # Submit the final form with the wrong password.
@ -3821,7 +3833,8 @@ class UserSignUpTest(ZulipTestCase):
HTTP_HOST=subdomain + ".testserver", HTTP_HOST=subdomain + ".testserver",
) )
self.assert_in_success_response( self.assert_in_success_response(
["We just need you to do one last thing.", "newuser@zulip.com"], result ["Enter your account details to complete registration.", "newuser@zulip.com"],
result,
) )
@patch( @patch(

View File

@ -72,6 +72,7 @@ from zerver.models import (
Stream, Stream,
UserProfile, UserProfile,
get_default_stream_groups, get_default_stream_groups,
get_org_type_display_name,
get_realm, get_realm,
get_source_profile, get_source_profile,
get_user_by_delivery_email, get_user_by_delivery_email,
@ -177,6 +178,14 @@ def check_prereg_key(
return prereg_object, realm_creation return prereg_object, realm_creation
def get_selected_realm_type_name(prereg_realm: Optional[PreregistrationRealm]) -> Optional[str]:
if prereg_realm is None:
# We show the selected realm type only when creating new realm.
return None
return get_org_type_display_name(prereg_realm.org_type)
@add_google_analytics @add_google_analytics
@require_post @require_post
def realm_register(*args: Any, **kwargs: Any) -> HttpResponse: def realm_register(*args: Any, **kwargs: Any) -> HttpResponse:
@ -597,6 +606,7 @@ def registration_helper(
Realm.ORG_TYPES.values(), key=lambda d: d["display_order"] Realm.ORG_TYPES.values(), key=lambda d: d["display_order"]
), ),
"default_email_address_visibility": default_email_address_visibility, "default_email_address_visibility": default_email_address_visibility,
"selected_realm_type_name": get_selected_realm_type_name(prereg_realm),
"email_address_visibility_admins_only": RealmUserDefault.EMAIL_ADDRESS_VISIBILITY_ADMINS, "email_address_visibility_admins_only": RealmUserDefault.EMAIL_ADDRESS_VISIBILITY_ADMINS,
"email_address_visibility_moderators": RealmUserDefault.EMAIL_ADDRESS_VISIBILITY_MODERATORS, "email_address_visibility_moderators": RealmUserDefault.EMAIL_ADDRESS_VISIBILITY_MODERATORS,
"email_address_visibility_nobody": RealmUserDefault.EMAIL_ADDRESS_VISIBILITY_NOBODY, "email_address_visibility_nobody": RealmUserDefault.EMAIL_ADDRESS_VISIBILITY_NOBODY,