mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-25 03:58:39 +02:00
pushing to pull on other device
This commit is contained in:
parent
b1ef0b597d
commit
dfd237755d
6 changed files with 197 additions and 23 deletions
|
@ -25,6 +25,8 @@ nameserversFormListener();
|
|||
hookupYesNoListener("other_contacts-has_other_contacts",'other-employees', 'no-other-employees');
|
||||
hookupYesNoListener("additional_details-has_anything_else_text",'anything-else', null);
|
||||
hookupYesNoListener("additional_details-has_cisa_representative",'cisa-representative', null);
|
||||
hookupYesNoListener("feb_naming_requirements", "", "domain-naming-requirements-details-container");
|
||||
|
||||
initializeUrbanizationToggle();
|
||||
|
||||
userProfileListener();
|
||||
|
|
|
@ -607,6 +607,68 @@ class DotGovDomainForm(RegistrarForm):
|
|||
},
|
||||
)
|
||||
|
||||
class ExecutiveNamingRequirementsYesNoForm(BaseYesNoForm):
|
||||
"""
|
||||
Form for verifying if the domain request meets the Federal Executive Branch domain naming requirements.
|
||||
If the "no" option is selected, details must be provided via the separate details form.
|
||||
"""
|
||||
|
||||
field_name = "feb_naming_requirements"
|
||||
|
||||
@property
|
||||
def form_is_checked(self):
|
||||
"""
|
||||
Determines the initial checked state of the form based on the domain_request's attributes.
|
||||
"""
|
||||
return self.domain_request.feb_naming_requirements
|
||||
|
||||
def clean(self):
|
||||
# Skip validation if this form is not applicable.
|
||||
if not (self.domain_request.is_federal() and self.domain_request.federal_type == "Executive"):
|
||||
# If not executive, default to "yes"
|
||||
self.cleaned_data["feb_naming_requirements"] = "yes"
|
||||
return self.cleaned_data
|
||||
|
||||
# Only validate the yes/no field here; details are handled by the separate details form.
|
||||
cleaned = super().clean()
|
||||
return cleaned
|
||||
|
||||
def to_database(self, obj: DomainRequest):
|
||||
"""
|
||||
Saves the cleaned data from this form to the DomainRequest object.
|
||||
"""
|
||||
if not self.is_valid():
|
||||
return
|
||||
obj.feb_naming_requirements = (self.cleaned_data["feb_naming_requirements"] == "yes")
|
||||
obj.save()
|
||||
|
||||
@classmethod
|
||||
def from_database(cls, obj):
|
||||
"""
|
||||
Retrieves initial data from the DomainRequest object to prepopulate the form.
|
||||
"""
|
||||
initial = {}
|
||||
if hasattr(obj, "feb_naming_requirements"):
|
||||
initial["feb_naming_requirements"] = "yes" if obj.feb_naming_requirements else "no"
|
||||
return initial
|
||||
|
||||
class ExecutiveNamingRequirementsDetailsForm(BaseDeletableRegistrarForm):
|
||||
JOIN = "feb_naming_requirements_details"
|
||||
|
||||
# Text area for additional details; rendered conditionally when "no" is selected.
|
||||
feb_naming_requirements_details = forms.CharField(
|
||||
widget=forms.Textarea(attrs={'maxlength': '2000'}),
|
||||
max_length=2000,
|
||||
required=True,
|
||||
label="",
|
||||
help_text="Maximum 2000 characters allowed.",
|
||||
)
|
||||
|
||||
def to_database(self, obj: DomainRequest):
|
||||
if not self.is_valid():
|
||||
return
|
||||
obj.feb_naming_requirements_details = self.cleaned_data["feb_naming_requirements_details"]
|
||||
obj.save()
|
||||
|
||||
class PurposeForm(RegistrarForm):
|
||||
purpose = forms.CharField(
|
||||
|
@ -625,7 +687,7 @@ class PurposeForm(RegistrarForm):
|
|||
],
|
||||
error_messages={"required": "Describe how you’ll use the .gov domain you’re requesting."},
|
||||
)
|
||||
|
||||
|
||||
|
||||
class OtherContactsYesNoForm(BaseYesNoForm):
|
||||
"""The yes/no field for the OtherContacts form."""
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 4.2.17 on 2025-02-13 22:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("registrar", "0140_alter_portfolioinvitation_additional_permissions_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
name="feb_naming_requirements",
|
||||
field=models.BooleanField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
name="feb_naming_requirements_details",
|
||||
field=models.TextField(blank=True, null=True),
|
||||
),
|
||||
]
|
|
@ -501,6 +501,16 @@ class DomainRequest(TimeStampedModel):
|
|||
on_delete=models.PROTECT,
|
||||
)
|
||||
|
||||
feb_naming_requirements = models.BooleanField(
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
feb_naming_requirements_details = models.TextField(
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
alternative_domains = models.ManyToManyField(
|
||||
"registrar.Website",
|
||||
blank=True,
|
||||
|
@ -1388,6 +1398,16 @@ class DomainRequest(TimeStampedModel):
|
|||
if self.has_anything_else_text is None or self.has_cisa_representative is None:
|
||||
has_details = False
|
||||
return has_details
|
||||
|
||||
def is_feb(self) -> bool:
|
||||
"""Is this domain request for a Federal Executive Branch agency?"""
|
||||
# if not self.generic_org_type:
|
||||
# # generic_org_type is either blank or None, assume no
|
||||
# return False
|
||||
# if self.generic_org_type == DomainRequest.OrganizationChoices.FEDERAL:
|
||||
# return self.federal_type == DomainRequest.FederalChoices.EXECUTIVE
|
||||
# return False
|
||||
return True # TODO: this is for testing, remove before merging
|
||||
|
||||
def is_federal(self) -> Union[bool, None]:
|
||||
"""Is this domain request for a federal agency?
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
{% load static field_helpers url_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
||||
<p>Before requesting a .gov domain, please make sure it meets <a class="usa-link" rel="noopener noreferrer" target="_blank" href="{% public_site_url 'domains/choosing' %}">our naming requirements</a>. Your domain name must:
|
||||
<p>Before requesting a .gov domain, please make sure it meets <a class="usa-link" rel="noopener noreferrer" target="_blank" href="{% if is_feb %}https://get.gov/domains/executive-branch-guidance/{% else %}{% public_site_url 'domains/choosing' %}{% endif %}">our naming requirements</a>. Your domain name must:
|
||||
<ul class="usa-list">
|
||||
<li>Be available </li>
|
||||
<li>Relate to your organization’s name, location, and/or services </li>
|
||||
<li>Relate to your organization's name, location, and/or services </li>
|
||||
<li>Be unlikely to mislead or confuse the general public (even if your domain is only intended for a specific audience) </li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>Names that <em>uniquely apply to your organization</em> are likely to be approved over names that could also apply to other organizations.
|
||||
{% if not is_federal %}In most instances, this requires including your state’s two-letter abbreviation.{% endif %}</p>
|
||||
{% if not is_federal %}In most instances, this requires including your state's two-letter abbreviation.{% endif %}</p>
|
||||
|
||||
{% if not portfolio %}
|
||||
<p>Requests for your organization’s initials or an abbreviated name might not be approved, but we encourage you to request the name you want.</p>
|
||||
<p>Requests for your organization's initials or an abbreviated name might not be approved, but we encourage you to request the name you want.</p>
|
||||
{% endif %}
|
||||
|
||||
<p>Note that <strong>only federal agencies can request generic terms</strong> like
|
||||
|
@ -41,9 +41,10 @@
|
|||
<legend>
|
||||
<h2>What .gov domain do you want?</h2>
|
||||
</legend>
|
||||
|
||||
<p id="domain_instructions" class="margin-top-05">After you enter your domain, we’ll make sure it’s available and that it meets some of our naming requirements. If your domain passes these initial checks, we’ll verify that it meets all our requirements after you complete the rest of this form.</p>
|
||||
|
||||
<p id="domain_instructions" class="margin-top-05">
|
||||
After you enter your domain, we'll make sure it's available and that it meets some of our naming requirements.
|
||||
If your domain passes these initial checks, we'll verify that it meets all our requirements after you complete the rest of this form.
|
||||
</p>
|
||||
{% with attr_aria_labelledby="domain_instructions domain_instructions2" attr_aria_describedby="id_dotgov_domain-requested_domain--toast" %}
|
||||
{# attr_validate / validate="domain" invokes code in getgov.min.js #}
|
||||
{% with append_gov=True attr_validate="domain" add_label_class="usa-sr-only" %}
|
||||
|
@ -63,10 +64,9 @@
|
|||
<legend>
|
||||
<h2>Alternative domains (optional)</h2>
|
||||
</legend>
|
||||
|
||||
<p id="alt_domain_instructions" class="margin-top-05">Are there other domains you’d like if we can’t give
|
||||
you your first choice?</p>
|
||||
|
||||
<p id="alt_domain_instructions" class="margin-top-05">
|
||||
Are there other domains you'd like if we can't give you your first choice?
|
||||
</p>
|
||||
{% with attr_aria_labelledby="alt_domain_instructions" %}
|
||||
{# Will probably want to remove blank-ok and do related cleanup when we implement delete #}
|
||||
{% with attr_validate="domain" append_gov=True add_label_class="usa-sr-only" add_class="blank-ok alternate-domain-input" %}
|
||||
|
@ -79,13 +79,12 @@
|
|||
{% endfor %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
|
||||
<button type="button" value="save" class="usa-button usa-button--unstyled usa-button--with-icon" id="add-form">
|
||||
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
||||
<use xlink:href="{%static 'img/sprite.svg'%}#add_circle"></use>
|
||||
</svg><span class="margin-left-05">Add another alternative</span>
|
||||
<use xlink:href="{% static 'img/sprite.svg' %}#add_circle"></use>
|
||||
</svg>
|
||||
<span class="margin-left-05">Add another alternative</span>
|
||||
</button>
|
||||
|
||||
<div class="margin-bottom-3">
|
||||
<button
|
||||
id="validate-alt-domains-availability"
|
||||
|
@ -94,10 +93,41 @@
|
|||
validate-for="{{ forms.1.requested_domain.auto_id }}"
|
||||
>Check availability</button>
|
||||
</div>
|
||||
|
||||
<p class="margin-top-05">
|
||||
If you're not sure this is the domain you want, that's ok. You can change the domain later.
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<p class="margin-top-05">If you’re not sure this is the domain you want, that’s ok. You can change the domain later. </p>
|
||||
{{ forms.2.management_form }}
|
||||
{{ forms.3.management_form }}
|
||||
|
||||
</fieldset>
|
||||
{% if is_feb %}
|
||||
<fieldset class="usa-fieldset margin-top-0 dotgov-domain-form">
|
||||
<legend>
|
||||
<h2>Does this submission meet each domain naming requirement?</h2>
|
||||
</legend>
|
||||
<p id="dotgov-domain-naming-requirements" class="margin-top-05">
|
||||
OMB will review each request against the domain
|
||||
<a class="usa-link" rel="noopener noreferrer" target="_blank" href="https://get.gov/domains/executive-branch-guidance/">
|
||||
naming requirements for executive branch agencies
|
||||
</a>.
|
||||
Agency submissions are expected to meet each requirement.
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.2.feb_naming_requirements %}
|
||||
{% endwith %}
|
||||
|
||||
{# Conditional Details Field – only shown when the executive naming requirements radio is "False" #}
|
||||
<div id="domain-naming-requirements-details-container" class="conditional-panel" style="display: none;">
|
||||
<p class="usa-label">
|
||||
Provide details below <span class="usa-label--required">*</span>
|
||||
</p>
|
||||
{% with add_label_class="usa-sr-only" attr_required="required" maxlength="2000" %}
|
||||
{% input_with_errors forms.3.feb_naming_requirements_details %}
|
||||
{% endwith %}
|
||||
<p class="usa-hint">Maximum 2000 characters allowed.</p>
|
||||
</div>
|
||||
</fieldset>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -466,6 +466,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
|||
"requested_domain__name": requested_domain_name,
|
||||
}
|
||||
context["domain_request_id"] = self.domain_request.id
|
||||
context["is_executive"] = self.domain_request.is_federal() and self.domain_request.federal_type == "Executive"
|
||||
return context
|
||||
|
||||
def get_step_list(self) -> list:
|
||||
|
@ -652,14 +653,52 @@ class CurrentSites(DomainRequestWizard):
|
|||
|
||||
class DotgovDomain(DomainRequestWizard):
|
||||
template_name = "domain_request_dotgov_domain.html"
|
||||
forms = [forms.DotGovDomainForm, forms.AlternativeDomainFormSet]
|
||||
forms = [
|
||||
forms.DotGovDomainForm,
|
||||
forms.AlternativeDomainFormSet,
|
||||
forms.ExecutiveNamingRequirementsYesNoForm,
|
||||
forms.ExecutiveNamingRequirementsDetailsForm,
|
||||
]
|
||||
|
||||
def get_context_data(self):
|
||||
context = super().get_context_data()
|
||||
context["generic_org_type"] = self.domain_request.generic_org_type
|
||||
context["federal_type"] = self.domain_request.federal_type
|
||||
context["is_feb"] = self.domain_request.is_feb()
|
||||
return context
|
||||
|
||||
def is_valid(self, forms_list: list) -> bool:
|
||||
"""
|
||||
Expected order of forms_list:
|
||||
0: DotGovDomainForm
|
||||
1: AlternativeDomainFormSet
|
||||
2: ExecutiveNamingRequirementsYesNoForm
|
||||
3: ExecutiveNamingRequirementsDetailsForm
|
||||
"""
|
||||
# If not a federal executive branch agency, mark executive-related forms for deletion.
|
||||
if not (self.domain_request.is_feb()):
|
||||
forms_list[2].mark_form_for_deletion()
|
||||
forms_list[3].mark_form_for_deletion()
|
||||
return all(form.is_valid() for form in forms_list)
|
||||
|
||||
valid = True
|
||||
yesno_form = forms_list[2]
|
||||
details_form = forms_list[3]
|
||||
|
||||
if yesno_form.cleaned_data.get("feb_naming_requirements") == "yes":
|
||||
# If the user selects "yes", no details are needed.
|
||||
details_form.mark_form_for_deletion()
|
||||
valid = all(
|
||||
form.is_valid() for i, form in enumerate(forms_list) if i != 3
|
||||
)
|
||||
else:
|
||||
# "No" was selected – details are required.
|
||||
valid = (
|
||||
yesno_form.is_valid() and
|
||||
details_form.is_valid() and
|
||||
all(form.is_valid() for i, form in enumerate(forms_list) if i not in [2, 3])
|
||||
)
|
||||
return valid
|
||||
|
||||
|
||||
class Purpose(DomainRequestWizard):
|
||||
template_name = "domain_request_purpose.html"
|
||||
|
@ -711,9 +750,7 @@ class OtherContacts(DomainRequestWizard):
|
|||
|
||||
|
||||
class AdditionalDetails(DomainRequestWizard):
|
||||
|
||||
template_name = "domain_request_additional_details.html"
|
||||
|
||||
forms = [
|
||||
forms.CisaRepresentativeYesNoForm,
|
||||
forms.CisaRepresentativeForm,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue