Skip to content

Commit

Permalink
Merge pull request #2032 from cisagov/za/update-field-helper-text
Browse files Browse the repository at this point in the history
Ticket #1946: Update field helper text
  • Loading branch information
zandercymatics authored Apr 23, 2024
2 parents da29752 + fe75724 commit 0daca56
Show file tree
Hide file tree
Showing 15 changed files with 1,623 additions and 81 deletions.
59 changes: 46 additions & 13 deletions src/registrar/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,34 @@ class Meta:
"user_permissions": NoAutocompleteFilteredSelectMultiple("user_permissions", False),
}

def __init__(self, *args, **kwargs):
"""Custom init to modify the user form"""
super(MyUserAdminForm, self).__init__(*args, **kwargs)
self._override_base_help_texts()

def _override_base_help_texts(self):
"""
Used to override pre-existing help texts in AbstractUser.
This is done to avoid modifying the base AbstractUser class.
"""
is_superuser = self.fields.get("is_superuser")
is_staff = self.fields.get("is_staff")
password = self.fields.get("password")

if is_superuser is not None:
is_superuser.help_text = "For development purposes only; provides superuser access on the database level."

if is_staff is not None:
is_staff.help_text = "Designates whether the user can log in to this admin site."

if password is not None:
# Link is copied from the base implementation of UserChangeForm.
link = f"../../{self.instance.pk}/password/"
password.help_text = (
"Raw passwords are not stored, so they will not display here. "
f'You can change the password using <a href="{link}">this form</a>.'
)


class DomainInformationAdminForm(forms.ModelForm):
"""This form utilizes the custom widget for its class's ManyToMany UIs."""
Expand Down Expand Up @@ -533,7 +561,7 @@ def overridden_email_field(self, obj):
analyst_fieldsets = (
(
None,
{"fields": ("password", "status")},
{"fields": ("status",)},
),
("Personal Info", {"fields": ("first_name", "last_name", "email")}),
(
Expand All @@ -559,7 +587,6 @@ def overridden_email_field(self, obj):
# NOT all fields are readonly for admin, otherwise we would have
# set this at the permissions level. The exception is 'status'
analyst_readonly_fields = [
"password",
"Personal Info",
"first_name",
"last_name",
Expand Down Expand Up @@ -1722,21 +1749,27 @@ def changeform_view(self, request, object_id=None, form_url="", extra_context=No
if domain is not None and hasattr(domain, "domain_info"):
extra_context["original_object"] = domain.domain_info

extra_context["state_help_message"] = Domain.State.get_admin_help_text(domain.state)
extra_context["domain_state"] = domain.get_state_display()

# Pass in what the an extended expiration date would be for the expiration date modal
years_to_extend_by = self._get_calculated_years_for_exp_date(domain)
try:
curr_exp_date = domain.registry_expiration_date
except KeyError:
# No expiration date was found. Return none.
extra_context["extended_expiration_date"] = None
return super().changeform_view(request, object_id, form_url, extra_context)
new_date = curr_exp_date + relativedelta(years=years_to_extend_by)
extra_context["extended_expiration_date"] = new_date
else:
extra_context["extended_expiration_date"] = None
self._set_expiration_date_context(domain, extra_context)

return super().changeform_view(request, object_id, form_url, extra_context)

def _set_expiration_date_context(self, domain, extra_context):
"""Given a domain, calculate the an extended expiration date
from the current registry expiration date."""
years_to_extend_by = self._get_calculated_years_for_exp_date(domain)
try:
curr_exp_date = domain.registry_expiration_date
except KeyError:
# No expiration date was found. Return none.
extra_context["extended_expiration_date"] = None
else:
new_date = curr_exp_date + relativedelta(years=years_to_extend_by)
extra_context["extended_expiration_date"] = new_date

def response_change(self, request, obj):
# Create dictionary of action functions
ACTION_FUNCTIONS = {
Expand Down

Large diffs are not rendered by default.

40 changes: 34 additions & 6 deletions src/registrar/models/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,31 @@ def get_help_text(cls, state) -> str:

return help_texts.get(state, "")

@classmethod
def get_admin_help_text(cls, state):
"""Returns a help message for a desired state for /admin. If none is found, an empty string is returned"""
admin_help_texts = {
cls.UNKNOWN: (
"The creator of the associated domain request has not logged in to "
"manage the domain since it was approved. "
'The state will switch to "DNS needed" after they access the domain in the registrar.'
),
cls.DNS_NEEDED: (
"Before this domain can be used, name server addresses need to be added within the registrar."
),
cls.READY: "This domain has name servers and is ready for use.",
cls.ON_HOLD: (
"While on hold, this domain won't resolve in DNS and "
"any infrastructure (like websites) will be offline."
),
cls.DELETED: (
"This domain was permanently removed from the registry. "
"The domain no longer resolves in DNS and any infrastructure (like websites) is offline."
),
}

return admin_help_texts.get(state, "")

class Cache(property):
"""
Python descriptor to turn class methods into properties.
Expand Down Expand Up @@ -992,22 +1017,25 @@ def __str__(self) -> str:
blank=False,
default=None, # prevent saving without a value
unique=True,
verbose_name="domain",
help_text="Fully qualified domain name",
verbose_name="domain",
)

state = FSMField(
max_length=21,
choices=State.choices,
default=State.UNKNOWN,
protected=True, # cannot change state directly, particularly in Django admin
# cannot change state directly, particularly in Django admin
protected=True,
# This must be defined for custom state help messages,
# as otherwise the view will purge the help field as it does not exist.
help_text=" ",
verbose_name="domain state",
help_text="Very basic info about the lifecycle of this domain object",
)

expiration_date = DateField(
null=True,
help_text=("Duplication of registry's expiration date saved for ease of reporting"),
help_text=("Date the domain expires in the registry"),
)

security_contact_registry_id = TextField(
Expand All @@ -1019,15 +1047,15 @@ def __str__(self) -> str:
deleted = DateField(
null=True,
editable=False,
help_text='Will appear blank unless the domain is in "deleted" state',
verbose_name="deleted on",
help_text="Deleted at date",
)

first_ready = DateField(
null=True,
editable=False,
help_text='Date when this domain first moved into "ready" state; date will never change',
verbose_name="first ready on",
help_text="The last time this domain moved into the READY state",
)

def isActive(self):
Expand Down
29 changes: 7 additions & 22 deletions src/registrar/models/domain_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class DomainInformation(TimeStampedModel):
"registrar.User",
on_delete=models.PROTECT,
related_name="information_created",
help_text="Person who submitted the domain request",
)

domain_request = models.OneToOneField(
Expand All @@ -55,7 +56,7 @@ class DomainInformation(TimeStampedModel):
blank=True,
null=True,
related_name="DomainRequest_info",
help_text="Associated domain request",
help_text="Request associated with this domain",
unique=True,
)

Expand All @@ -73,7 +74,6 @@ class DomainInformation(TimeStampedModel):
null=True,
blank=True,
verbose_name="election office",
help_text="Is your organization an election office?",
)

# TODO - Ticket #1911: stub this data from DomainRequest
Expand All @@ -82,97 +82,84 @@ class DomainInformation(TimeStampedModel):
choices=DomainRequest.OrgChoicesElectionOffice.choices,
null=True,
blank=True,
help_text="Type of organization - Election office",
help_text='"Election" appears after the org type if it\'s an election office.',
)

federally_recognized_tribe = models.BooleanField(
null=True,
help_text="Is the tribe federally recognized",
)

state_recognized_tribe = models.BooleanField(
null=True,
help_text="Is the tribe recognized by a state",
)

tribe_name = models.CharField(
null=True,
blank=True,
help_text="Name of tribe",
)

federal_agency = models.CharField(
choices=AGENCY_CHOICES,
null=True,
blank=True,
help_text="Federal agency",
)

federal_type = models.CharField(
max_length=50,
choices=BranchChoices.choices,
null=True,
blank=True,
help_text="Federal government branch",
)

is_election_board = models.BooleanField(
null=True,
blank=True,
verbose_name="election office",
help_text="Is your organization an election office?",
)

organization_name = models.CharField(
null=True,
blank=True,
help_text="Organization name",
db_index=True,
)
address_line1 = models.CharField(
null=True,
blank=True,
help_text="Street address",
verbose_name="address line 1",
)
address_line2 = models.CharField(
null=True,
blank=True,
help_text="Street address line 2 (optional)",
verbose_name="address line 2",
)
city = models.CharField(
null=True,
blank=True,
help_text="City",
)
state_territory = models.CharField(
max_length=2,
choices=StateTerritoryChoices.choices,
null=True,
blank=True,
verbose_name="state / territory",
help_text="State, territory, or military post",
)
zipcode = models.CharField(
max_length=10,
null=True,
blank=True,
help_text="Zip code",
verbose_name="zip code",
db_index=True,
verbose_name="zip code",
)
urbanization = models.CharField(
null=True,
blank=True,
help_text="Urbanization (required for Puerto Rico only)",
help_text="Required for Puerto Rico only",
verbose_name="urbanization",
)

about_your_organization = models.TextField(
null=True,
blank=True,
help_text="Information about your organization",
)

authorizing_official = models.ForeignKey(
Expand All @@ -190,7 +177,6 @@ class DomainInformation(TimeStampedModel):
null=True,
# Access this information via Domain as "domain.domain_info"
related_name="domain_info",
help_text="Domain to which this information belongs",
)

# This is the contact information provided by the domain requestor. The
Expand All @@ -201,6 +187,7 @@ class DomainInformation(TimeStampedModel):
blank=True,
related_name="submitted_domain_requests_information",
on_delete=models.PROTECT,
help_text='Person listed under "your contact information" in the request form',
)

purpose = models.TextField(
Expand All @@ -219,13 +206,12 @@ class DomainInformation(TimeStampedModel):
no_other_contacts_rationale = models.TextField(
null=True,
blank=True,
help_text="Reason for listing no additional contacts",
help_text="Required if creator does not list other employees",
)

anything_else = models.TextField(
null=True,
blank=True,
help_text="Anything else?",
)

is_policy_acknowledged = models.BooleanField(
Expand All @@ -237,7 +223,6 @@ class DomainInformation(TimeStampedModel):
notes = models.TextField(
null=True,
blank=True,
help_text="Notes about the request",
)

def __str__(self):
Expand Down
Loading

0 comments on commit 0daca56

Please sign in to comment.