Redirect logic

This commit is contained in:
zandercymatics 2024-05-13 12:52:35 -06:00
parent 7ec39e7d13
commit 4592b0c9e6
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
7 changed files with 112 additions and 63 deletions

View file

@ -895,13 +895,7 @@ function hideDeletedForms() {
// Lock the edit button while this operation occurs // Lock the edit button while this operation occurs
button.disabled = true button.disabled = true
if (fieldName == "full_name"){
let nameFields = ["first_name", "middle_name", "last_name"]
handleFullNameField(fieldName, nameFields);
}else {
showInputFieldHideReadonlyField(fieldName, button); showInputFieldHideReadonlyField(fieldName, button);
}
button.classList.add('display-none'); button.classList.add('display-none');
// Unlock after it completes // Unlock after it completes
@ -931,9 +925,14 @@ function hideDeletedForms() {
let errorMessage = document.querySelector(`#id_${fieldName}__error-message`); let errorMessage = document.querySelector(`#id_${fieldName}__error-message`);
if (errorMessage) { if (errorMessage) {
if (fieldName == "full_name"){
let nameFields = ["first_name", "middle_name", "last_name"]
handleFullNameField(fieldName, nameFields);
}else {
button.click() button.click()
} }
} }
}
}); });
}); });
} }

View file

@ -1,6 +1,5 @@
from django import forms from django import forms
from phonenumber_field.formfields import PhoneNumberField # type: ignore from phonenumber_field.formfields import PhoneNumberField # type: ignore
from django.core.validators import MaxLengthValidator
class ContactForm(forms.Form): class ContactForm(forms.Form):
@ -10,29 +9,25 @@ class ContactForm(forms.Form):
cleaned_data = super().clean() cleaned_data = super().clean()
# Remove the full name property # Remove the full name property
if "full_name" in cleaned_data: if "full_name" in cleaned_data:
full_name: str = cleaned_data["full_name"]
if full_name:
name_fields = full_name.split(" ")
cleaned_data["first_name"] = name_fields[0]
if len(name_fields) == 2:
cleaned_data["last_name"] = " ".join(name_fields[1:])
elif len(name_fields) > 2:
cleaned_data["middle_name"] = name_fields[1]
cleaned_data["last_name"] = " ".join(name_fields[2:])
else:
cleaned_data["middle_name"] = None
cleaned_data["last_name"] = None
# Delete the full name element as we don't need it anymore
del cleaned_data["full_name"] del cleaned_data["full_name"]
return cleaned_data return cleaned_data
def to_database(self, obj):
"""
Adds this form's cleaned data to `obj` and saves `obj`.
Does nothing if form is not valid.
"""
if not self.is_valid():
return
for name, value in self.cleaned_data.items():
setattr(obj, name, value)
obj.save()
@classmethod
def from_database(cls, obj):
"""Returns a dict of form field values gotten from `obj`."""
if obj is None:
return {}
return {name: getattr(obj, name) for name in cls.declared_fields.keys()} # type: ignore
full_name = forms.CharField( full_name = forms.CharField(
label="Full name", label="Full name",
error_messages={"required": "Enter your full name"}, error_messages={"required": "Enter your full name"},
@ -57,7 +52,6 @@ class ContactForm(forms.Form):
) )
email = forms.EmailField( email = forms.EmailField(
label="Organization email", label="Organization email",
max_length=None,
required=False, required=False,
) )
phone = PhoneNumberField( phone = PhoneNumberField(

View file

@ -92,6 +92,13 @@ class Contact(TimeStampedModel):
names = [n for n in [self.first_name, self.middle_name, self.last_name] if n] names = [n for n in [self.first_name, self.middle_name, self.last_name] if n]
return " ".join(names) if names else "Unknown" return " ".join(names) if names else "Unknown"
@property
def full_name(self):
"""
Returns the full name (first_name, middle_name, last_name) of this contact.
"""
return self.get_formatted_name()
def has_contact_info(self): def has_contact_info(self):
return bool(self.title or self.email or self.phone) return bool(self.title or self.email or self.phone)
@ -126,15 +133,3 @@ class Contact(TimeStampedModel):
return str(self.pk) return str(self.pk)
else: else:
return "" return ""
@property
def full_name(self, separator=" "):
"""
Returns the full name (first_name, middle_name, last_name) of this contact.
Seperator (which defaults to a blank space) determines the seperator for each of those fields.
For instance, with seperator=", " - this function would return this:
"First, Middle, Last"
"""
# Filter out empty strings to avoid extra spaces or separators
parts = [self.first_name or "", self.middle_name or "", self.last_name or ""]
return separator.join(parts)

View file

@ -261,3 +261,23 @@ class CreateOrUpdateOrganizationTypeHelper:
return False return False
else: else:
return True return True
def to_database(form, obj):
"""
Adds the form's cleaned data to `obj` and saves `obj`.
Does nothing if form is not valid.
"""
if not form.is_valid():
return None
for name, value in form.cleaned_data.items():
setattr(obj, name, value)
obj.save()
def from_database(form_class, obj):
"""Returns a dict of form field values gotten from `obj`."""
if obj is None:
return {}
return {name: getattr(obj, name) for name in form_class.declared_fields.keys()} # type: ignore

View file

@ -23,7 +23,8 @@ class CheckUserProfileMiddleware:
# Check if setup is not finished # Check if setup is not finished
finished_setup = hasattr(request.user, "finished_setup") and request.user.finished_setup finished_setup = hasattr(request.user, "finished_setup") and request.user.finished_setup
if request.user.is_authenticated and not finished_setup: if request.user.is_authenticated and not finished_setup:
setup_page = reverse("finish-contact-profile-setup", kwargs={'pk': request.user.contact.pk}) # redirect_to_domain_request = request.GET.get('domain_request', "") != ""
setup_page = reverse("finish-contact-profile-setup", kwargs={"pk": request.user.contact.pk})
logout_page = reverse("logout") logout_page = reverse("logout")
excluded_pages = [ excluded_pages = [
setup_page, setup_page,
@ -32,6 +33,7 @@ class CheckUserProfileMiddleware:
# Don't redirect on excluded pages (such as the setup page itself) # Don't redirect on excluded pages (such as the setup page itself)
if not any(request.path.startswith(page) for page in excluded_pages): if not any(request.path.startswith(page) for page in excluded_pages):
# Check if 'request' query parameter is not 'True'
# Redirect to the setup page # Redirect to the setup page
return HttpResponseRedirect(setup_page) return HttpResponseRedirect(setup_page)

View file

@ -24,7 +24,6 @@
<h1>Finish setting up your profile</h1> <h1>Finish setting up your profile</h1>
<p> <p>
{% public_site_url 'help/account-management/#get-help-with-login.gov' %}
We <a href="{% public_site_url 'domains/requirements/#what-.gov-domain-registrants-must-do' %}">require</a> We <a href="{% public_site_url 'domains/requirements/#what-.gov-domain-registrants-must-do' %}">require</a>
that you maintain accurate contact information. that you maintain accurate contact information.
The details you provide will only be used to support the administration of .gov and wont be made public. The details you provide will only be used to support the administration of .gov and wont be made public.
@ -79,9 +78,15 @@
</fieldset> </fieldset>
<div> <div>
<button type="submit" name="submit_button" class="usa-button"> {% if confirm_changes %}
<button type="submit" name="contact_setup_save_button" class="usa-button">
Save Save
</button> </button>
{% else %}
<button type="submit" name="contact_setup_submit_button" class="usa-button">
Save and continue
</button>
{% endif %}
</div> </div>
{% block form_fields %}{% endblock %} {% block form_fields %}{% endblock %}
</main> </main>

View file

@ -1,9 +1,12 @@
from django.http import HttpResponseRedirect
from django.urls import reverse from django.urls import reverse
from registrar.forms.contact import ContactForm from registrar.forms.contact import ContactForm
from registrar.models.contact import Contact from registrar.models.contact import Contact
from registrar.templatetags.url_helpers import public_site_url
from registrar.views.utility.permission_views import ContactPermissionView from registrar.views.utility.permission_views import ContactPermissionView
from django.views.generic.edit import FormMixin from django.views.generic.edit import FormMixin
from registrar.models.utility.generic_helper import to_database, from_database
from django.utils.safestring import mark_safe
# TODO we can and probably should generalize this at this rate. # TODO we can and probably should generalize this at this rate.
class BaseContactView(ContactPermissionView): class BaseContactView(ContactPermissionView):
@ -30,14 +33,15 @@ class BaseContactView(ContactPermissionView):
self.object = cached_contact self.object = cached_contact
else: else:
self.object = self.get_object() self.object = self.get_object()
self._update_session_with_contact() self._update_session_with_contact()
def _update_session_with_contact(self): def _update_session_with_contact(self):
""" """
Set contact pk in the session cache Set contact pk in the session cache
""" """
domain_pk = "contact:" + str(self.kwargs.get("pk")) contact_pk = "contact:" + str(self.kwargs.get("pk"))
self.session[domain_pk] = self.object self.session[contact_pk] = self.object
class ContactFormBaseView(BaseContactView, FormMixin): class ContactFormBaseView(BaseContactView, FormMixin):
@ -50,13 +54,9 @@ class ContactFormBaseView(BaseContactView, FormMixin):
# Set the current contact object in cache # Set the current contact object in cache
self._set_contact(request) self._set_contact(request)
# Get the current form and validate it
form = self.get_form() form = self.get_form()
return self.check_form(form) # Get the current form and validate it
# TODO rename?
def check_form(self, form):
return self.form_valid(form) if form.is_valid() else self.form_invalid(form) return self.form_valid(form) if form.is_valid() else self.form_invalid(form)
def form_invalid(self, form): def form_invalid(self, form):
@ -74,31 +74,65 @@ class ContactProfileSetupView(ContactFormBaseView):
form_class = ContactForm form_class = ContactForm
model = Contact model = Contact
def post(self, request, *args, **kwargs):
"""Form submission posts to this view.
This post method harmonizes using BaseContactView and FormMixin
"""
# Set the current contact object in cache
self._set_contact(request)
form = self.get_form()
# Get the current form and validate it
if form.is_valid():
if "redirect_to_home" not in self.session or not self.session["redirect_to_home"]:
self.session["redirect_to_home"] = "contact_setup_submit_button" in request.POST
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_success_url(self): def get_success_url(self):
"""Redirect to the nameservers page for the domain.""" """Redirect to the nameservers page for the domain."""
# TODO - some logic should exist that navigates them to the domain request page if # TODO - some logic should exist that navigates them to the domain request page if
# they clicked it on get.gov # they clicked it on get.gov
# Add a notification that the update was successful # Add a notification that the update was successful
if "redirect_to_home" in self.session and self.session["redirect_to_home"]:
return reverse("home") return reverse("home")
else:
# Redirect to the same page with a query parameter to confirm changes
self.session["redirect_to_home"] = True
return reverse("finish-contact-profile-setup", kwargs={"pk": self.object.pk})
def form_valid(self, form): def form_valid(self, form):
self.request.user.finished_setup = True self.request.user.finished_setup = True
self.request.user.save() self.request.user.save()
form.to_database(self.object) to_database(form=form, obj=self.object)
self._update_session_with_contact() self._update_session_with_contact()
return super().form_valid(form) return super().form_valid(form)
def get_initial(self): def get_initial(self):
"""The initial value for the form (which is a formset here).""" """The initial value for the form (which is a formset here)."""
db_object = self.form_class.from_database(self.object) db_object = from_database(form_class=self.form_class, obj=self.object)
return db_object return db_object
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context["email_sublabel_text"] = ( context["email_sublabel_text"] = self._email_sublabel_text()
if "redirect_to_home" in self.session and self.session["redirect_to_home"]:
context['confirm_changes'] = True
return context
def _email_sublabel_text(self):
"""Returns the lengthy sublabel for the email field"""
help_url = public_site_url('help/account-management/#get-help-with-login.gov')
return mark_safe(
"We recommend using your work email for your .gov account. " "We recommend using your work email for your .gov account. "
"If the wrong email is displayed below, youll need to update your Login.gov account " "If the wrong email is displayed below, youll need to update your Login.gov account "
"and log back in. Get help with your Login.gov account.") f'and log back in. <a class="usa-link" href={help_url}>Get help with your Login.gov account.</a>'
return context )