From 80b00933b13321e103ac4c308cb3a27dc2a255a8 Mon Sep 17 00:00:00 2001 From: Sahil Batra Date: Wed, 1 Mar 2023 15:17:38 +0530 Subject: [PATCH] templates: Add realm information fields in create_realm.html. We now show inputs for realm details like name, type and URL in the create_realm.html template opened for "/new" url and these information will be stored in PreregistrationRealm objects in further commits. We add a new class RealmDetailsForm in forms.py for this such that it is used as a base class for RealmCreationForm and we define RealmDetailsForm such that we can use it as a subclass for RegistrationForm as well to avoid duplication. --- templates/zerver/create_realm.html | 23 +++++++++------- templates/zerver/realm_creation_form.html | 2 +- templates/zerver/register.html | 5 +++- web/e2e-tests/realm-creation.test.ts | 7 +++-- web/src/portico/signup.js | 4 +-- web/styles/portico/portico_signin.css | 9 ++++++- zerver/context_processors.py | 12 ++++++++- zerver/forms.py | 32 ++++++++++++++++++++++- zerver/views/registration.py | 16 ++++++++++-- 9 files changed, 87 insertions(+), 23 deletions(-) diff --git a/templates/zerver/create_realm.html b/templates/zerver/create_realm.html index 126625f360..cc9fbe546c 100644 --- a/templates/zerver/create_realm.html +++ b/templates/zerver/create_realm.html @@ -11,7 +11,7 @@
-
+

{{ _("Create a new Zulip organization") }}

@@ -19,23 +19,26 @@
{{ csrf_input }} + + {% include 'zerver/realm_creation_form.html' %} +
- + id="email" name="email" required /> +
- + {% if form.email.errors %} + {% for error in form.email.errors %} +
{{ error }}
+ {% endfor %} + {% endif %} +
+
- - {% if form.email.errors %} - {% for error in form.email.errors %} -
{{ error }}
- {% endfor %} - {% endif %}
{% trans %} Or import diff --git a/templates/zerver/realm_creation_form.html b/templates/zerver/realm_creation_form.html index f335a31e9b..1dceedbb02 100644 --- a/templates/zerver/realm_creation_form.html +++ b/templates/zerver/realm_creation_form.html @@ -3,7 +3,7 @@ + name="realm_name" maxlength="{{ MAX_REALM_NAME_LENGTH }}" required {% if not user_registration_form %}autofocus{% endif %} />
{% if form.realm_name.errors %} diff --git a/templates/zerver/register.html b/templates/zerver/register.html index 11aaa25f8b..b94ef59fe8 100644 --- a/templates/zerver/register.html +++ b/templates/zerver/register.html @@ -34,7 +34,10 @@ Form is validated both client-side using jquery-validation (see signup.js) and s
{% if creating_new_realm %} {{ _('Your organization') }} - {% include 'zerver/realm_creation_form.html' %} + {% with %} + {% set user_registration_form = "true" %} + {% include 'zerver/realm_creation_form.html' %} + {% endwith %} {% endif %}
diff --git a/web/e2e-tests/realm-creation.test.ts b/web/e2e-tests/realm-creation.test.ts index c921557fcc..cfb70c3dfb 100644 --- a/web/e2e-tests/realm-creation.test.ts +++ b/web/e2e-tests/realm-creation.test.ts @@ -5,7 +5,6 @@ import type {Page} from "puppeteer"; import * as common from "./lib/common"; const email = "alice@test.example.com"; -const subdomain = "testsubdomain"; const organization_name = "Awesome Organization"; const host = "zulipdev.com:9981"; @@ -15,6 +14,9 @@ async function realm_creation_tests(page: Page): Promise { // submit the email for realm creation. await page.waitForSelector("#email"); await page.type("#email", email); + await page.type("#id_team_name", organization_name); + await page.$eval("#realm_in_root_domain", (el) => (el as HTMLInputElement).click()); + await Promise.all([ page.waitForNavigation(), page.$eval("#create_realm", (form) => (form as HTMLFormElement).submit()), @@ -50,15 +52,12 @@ async function realm_creation_tests(page: Page): Promise { // fill the form. const params = { - realm_name: organization_name, - realm_subdomain: subdomain, full_name: "Alice", password: "passwordwhichisnotreallycomplex", terms: true, }; // For some reason, page.click() does not work this for particular checkbox // so use page.$eval here to call the .click method in the browser. - await page.$eval("#realm_in_root_domain", (el) => (el as HTMLInputElement).click()); await common.fill_form(page, "#registration", params); await page.$eval("#registration", (form) => (form as HTMLFormElement).submit()); diff --git a/web/src/portico/signup.js b/web/src/portico/signup.js index 6bbca8bb0e..dc4510742e 100644 --- a/web/src/portico/signup.js +++ b/web/src/portico/signup.js @@ -45,7 +45,7 @@ $(() => { "#id_new_password2 ~ .password_visibility_toggle", ); - $("#registration, #password_reset").validate({ + $("#registration, #password_reset", "#create_realm").validate({ rules: { password: "password_strength", new_password1: "password_strength", @@ -133,7 +133,7 @@ $(() => { $("input[name='next']").attr("value", next_value + window.location.hash); } - $("#send_confirm", "#create_realm").validate({ + $("#send_confirm").validate({ errorElement: "div", errorPlacement($error) { $(".email-frontend-error").empty(); diff --git a/web/styles/portico/portico_signin.css b/web/styles/portico/portico_signin.css index deeca5d65c..caf212a7d9 100644 --- a/web/styles/portico/portico_signin.css +++ b/web/styles/portico/portico_signin.css @@ -46,6 +46,12 @@ html { } } +#new-realm-creation { + .get-started { + font-size: 2rem; + } +} + .bottom-text-large { text-align: center; margin-top: 20px; @@ -877,7 +883,8 @@ button#register_auth_button_gitlab { } } -#registration { +#registration, +#new-realm-creation { width: auto; padding: 0; margin: 30px; diff --git a/zerver/context_processors.py b/zerver/context_processors.py index 7a1dcf49f6..fec636d6b9 100644 --- a/zerver/context_processors.py +++ b/zerver/context_processors.py @@ -19,7 +19,7 @@ from zerver.lib.realm_description import get_realm_rendered_description, get_rea from zerver.lib.realm_icon import get_realm_icon_url from zerver.lib.request import RequestNotes from zerver.lib.send_email import FromAddress -from zerver.lib.subdomains import get_subdomain +from zerver.lib.subdomains import get_subdomain, is_root_domain_available from zerver.models import Realm, UserProfile, get_realm from zproject.backends import ( AUTH_BACKEND_NAME_MAP, @@ -256,3 +256,13 @@ def latest_info_context() -> Dict[str, str]: "latest_release_announcement": LATEST_RELEASE_ANNOUNCEMENT, } return context + + +def get_realm_create_form_context() -> Dict[str, Any]: + context = { + "MAX_REALM_NAME_LENGTH": str(Realm.MAX_REALM_NAME_LENGTH), + "MAX_REALM_SUBDOMAIN_LENGTH": str(Realm.MAX_REALM_SUBDOMAIN_LENGTH), + "root_domain_available": is_root_domain_available(), + "sorted_realm_types": sorted(Realm.ORG_TYPES.values(), key=lambda d: d["display_order"]), + } + return context diff --git a/zerver/forms.py b/zerver/forms.py index 11fc3e0bbf..14623defa0 100644 --- a/zerver/forms.py +++ b/zerver/forms.py @@ -259,10 +259,40 @@ def email_is_not_disposable(email: str) -> None: raise ValidationError(_("Please use your real email address.")) -class RealmCreationForm(forms.Form): +class RealmDetailsForm(forms.Form): + realm_subdomain = forms.CharField(max_length=Realm.MAX_REALM_SUBDOMAIN_LENGTH, required=False) + realm_type = forms.TypedChoiceField( + coerce=int, choices=[(t["id"], t["name"]) for t in Realm.ORG_TYPES.values()] + ) + realm_name = forms.CharField(max_length=Realm.MAX_REALM_NAME_LENGTH) + + def __init__(self, *args: Any, **kwargs: Any) -> None: + self.realm_creation = kwargs["realm_creation"] + del kwargs["realm_creation"] + + super().__init__(*args, **kwargs) + + def clean_realm_subdomain(self) -> str: + if not self.realm_creation: + # This field is only used if realm_creation + return "" + + subdomain = self.cleaned_data["realm_subdomain"] + if "realm_in_root_domain" in self.data: + subdomain = Realm.SUBDOMAIN_FOR_ROOT_DOMAIN + + check_subdomain_available(subdomain) + return subdomain + + +class RealmCreationForm(RealmDetailsForm): # This form determines whether users can create a new realm. email = forms.EmailField(validators=[email_not_system_bot, email_is_not_disposable]) + def __init__(self, *args: Any, **kwargs: Any) -> None: + kwargs["realm_creation"] = True + super().__init__(*args, **kwargs) + class LoggingSetPasswordForm(SetPasswordForm): new_password1 = forms.CharField( diff --git a/zerver/views/registration.py b/zerver/views/registration.py index 8561c8be70..009b218021 100644 --- a/zerver/views/registration.py +++ b/zerver/views/registration.py @@ -34,7 +34,11 @@ from zerver.actions.user_settings import ( do_change_password, do_change_user_setting, ) -from zerver.context_processors import get_realm_from_request, login_context +from zerver.context_processors import ( + get_realm_create_form_context, + get_realm_from_request, + login_context, +) from zerver.decorator import add_google_analytics, do_login, require_post from zerver.forms import ( FindMyTeamForm, @@ -698,10 +702,18 @@ def create_realm(request: HttpRequest, creation_key: Optional[str] = None) -> Ht return HttpResponseRedirect(url) else: form = RealmCreationForm() + + context = get_realm_create_form_context() + context.update( + { + "form": form, + "current_url": request.get_full_path, + } + ) return TemplateResponse( request, "zerver/create_realm.html", - context={"form": form, "current_url": request.get_full_path}, + context=context, )