mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-24 03:30:50 +02:00
Merge branch 'cb/3212-subissues' of https://github.com/cisagov/manage.get.gov into cb/3212-subissues
This commit is contained in:
commit
6ea38c3a07
19 changed files with 379 additions and 271 deletions
|
@ -2742,38 +2742,6 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportRegistrarModelAdmin):
|
|||
portfolio_urbanization.short_description = "Urbanization" # type: ignore
|
||||
|
||||
# ------ FEB fields ------
|
||||
def feb_naming_requirements_details(self, obj):
|
||||
return obj.feb_naming_requirements_details if obj.feb_naming_requirements else ""
|
||||
|
||||
feb_naming_requirements_details.short_description = "Domain Name Rationale:" # type: ignore
|
||||
|
||||
def feb_purpose_choice(self, obj):
|
||||
return obj.feb_purpose_choice if obj.feb_purpose_choice else ""
|
||||
|
||||
feb_purpose_choice.short_description = "Purpose type:" # type: ignore
|
||||
|
||||
def time_frame_details(self, obj):
|
||||
return obj.time_frame_details if obj.has_timeframe else ""
|
||||
|
||||
time_frame_details.short_description = "Target time frame:" # type: ignore
|
||||
|
||||
def interagency_initiative_details(self, obj):
|
||||
return obj.interagency_initiative_details if obj.is_interagency_initiative else ""
|
||||
|
||||
interagency_initiative_details.short_description = "Interagency Initiative:" # type: ignore
|
||||
|
||||
def eop_stakeholder_first_name(self, obj):
|
||||
return obj.eop_stakeholder_first_name if obj.eop_stakeholder_first_name else ""
|
||||
|
||||
def eop_stakeholder_last_name(self, obj):
|
||||
return obj.eop_stakeholder_last_name if obj.eop_stakeholder_last_name else ""
|
||||
|
||||
def eop_stakeholder_email(self, obj):
|
||||
return obj.eop_stakeholder_email if obj.eop_stakeholder_email else ""
|
||||
|
||||
eop_stakeholder_first_name.short_description = "EOP Stakeholder First Name" # type: ignore
|
||||
eop_stakeholder_last_name.short_description = "EOP Stakeholder Last Name" # type: ignore
|
||||
eop_stakeholder_email.short_description = "EOP Stakeholder Email" # type: ignore
|
||||
|
||||
# This is just a placeholder. This field will be populated in the detail_table_fieldset view.
|
||||
# This is not a field that exists on the model.
|
||||
|
@ -2878,7 +2846,6 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportRegistrarModelAdmin):
|
|||
"cisa_representative_email",
|
||||
"eop_stakeholder_first_name",
|
||||
"eop_stakeholder_last_name",
|
||||
"eop_stakeholder_email",
|
||||
]
|
||||
},
|
||||
),
|
||||
|
@ -3091,39 +3058,41 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportRegistrarModelAdmin):
|
|||
def get_fieldsets(self, request, obj=None):
|
||||
fieldsets = super().get_fieldsets(request, obj)
|
||||
|
||||
excluded_fields = set()
|
||||
feb_fields = [
|
||||
"feb_naming_requirements_details",
|
||||
"feb_purpose_choice",
|
||||
"time_frame_details",
|
||||
"interagency_initiative_details",
|
||||
"eop_stakeholder_first_name",
|
||||
"eop_stakeholder_last_name",
|
||||
]
|
||||
|
||||
org_fields = [
|
||||
"portfolio",
|
||||
"sub_organization",
|
||||
"requested_suborganization",
|
||||
"suborganization_city",
|
||||
"suborganization_state_territory",
|
||||
]
|
||||
|
||||
org_flag = flag_is_active_for_user(request.user, "organization_requests")
|
||||
# Hide FEB fields for non-FEB requests
|
||||
if not (obj and obj.portfolio and obj.is_feb()):
|
||||
excluded_fields.update(feb_fields)
|
||||
|
||||
# Hide certain portfolio and suborg fields behind the organization requests flag
|
||||
# if it is not enabled
|
||||
if not flag_is_active_for_user(request.user, "organization_requests"):
|
||||
excluded_fields = [
|
||||
"portfolio",
|
||||
"sub_organization",
|
||||
"requested_suborganization",
|
||||
"suborganization_city",
|
||||
"suborganization_state_territory",
|
||||
]
|
||||
# Hide FEB fields behind the organization requests flag
|
||||
# and only show them if the portfolio is executive
|
||||
if not (obj and obj.portfolio and obj.portfolio.federal_type == BranchChoices.EXECUTIVE):
|
||||
excluded_fields.extend(
|
||||
[
|
||||
"feb_naming_requirements_details",
|
||||
"feb_purpose_choice",
|
||||
"time_frame_details",
|
||||
"interagency_initiative_details",
|
||||
"eop_stakeholder_first_name",
|
||||
"eop_stakeholder_last_name",
|
||||
"eop_stakeholder_email",
|
||||
]
|
||||
)
|
||||
# This makes .gov domain collapsable underneath Requested By
|
||||
fieldsets[2][1]["classes"] = ["collapse--dgfieldset"]
|
||||
modified_fieldsets = []
|
||||
for name, data in fieldsets:
|
||||
fields = data.get("fields", [])
|
||||
fields = tuple(field for field in fields if field not in excluded_fields)
|
||||
modified_fieldsets.append((name, {**data, "fields": fields}))
|
||||
return modified_fieldsets
|
||||
return fieldsets
|
||||
if not org_flag:
|
||||
excluded_fields.update(org_fields)
|
||||
excluded_fields.update(feb_fields)
|
||||
|
||||
modified_fieldsets = []
|
||||
for name, data in fieldsets:
|
||||
fields = data.get("fields", [])
|
||||
fields = tuple(field for field in fields if field not in excluded_fields)
|
||||
modified_fieldsets.append((name, {**data, "fields": fields}))
|
||||
return modified_fieldsets
|
||||
|
||||
# Trigger action when a fieldset is changed
|
||||
def save_model(self, request, obj, form, change):
|
||||
|
|
|
@ -1,41 +1,105 @@
|
|||
import { showElement } from './helpers.js';
|
||||
|
||||
// Flag to track if we're in the initial page load
|
||||
let isInitialLoad = true;
|
||||
|
||||
export const domain_purpose_choice_callbacks = {
|
||||
'new': {
|
||||
callback: function(value, element) {
|
||||
callback: function(value, element, event) {
|
||||
// Only clear errors if this is a user-initiated event (not initial page load)
|
||||
if (!isInitialLoad) {
|
||||
clearErrors(element);
|
||||
}
|
||||
|
||||
//show the purpose details container
|
||||
showElement(element);
|
||||
// change just the text inside the em tag
|
||||
const labelElement = element.querySelector('.usa-label em');
|
||||
labelElement.innerHTML = 'Explain why a new domain is required and why a ' +
|
||||
'subdomain of an existing domain doesn\'t meet your needs.' +
|
||||
const labelElement = element.querySelector('p em');
|
||||
labelElement.innerHTML = 'Explain why a new domain name is needed instead of using a' +
|
||||
'subdomain of an existing website.' +
|
||||
'<br><br>' + // Adding double line break for spacing
|
||||
'Include any data that supports a clear public benefit or ' +
|
||||
'evidence user need for this new domain. ' +
|
||||
'Include any information or data that shows how the new domain would ' +
|
||||
'benefit the public or meet user needs. ' +
|
||||
'<span class="usa-label--required">*</span>';
|
||||
|
||||
// Mark that we're no longer in initial load
|
||||
isInitialLoad = false;
|
||||
},
|
||||
element: document.getElementById('purpose-details-container')
|
||||
},
|
||||
'redirect': {
|
||||
callback: function(value, element) {
|
||||
callback: function(value, element, event) {
|
||||
// Only clear errors if this is a user-initiated event (not initial page load)
|
||||
if (!isInitialLoad) {
|
||||
clearErrors(element);
|
||||
}
|
||||
|
||||
// show the purpose details container
|
||||
showElement(element);
|
||||
// change just the text inside the em tag
|
||||
const labelElement = element.querySelector('.usa-label em');
|
||||
const labelElement = element.querySelector('p em');
|
||||
labelElement.innerHTML = 'Explain why a redirect is necessary. ' +
|
||||
'<span class="usa-label--required">*</span>';
|
||||
|
||||
// Mark that we're no longer in initial load
|
||||
isInitialLoad = false;
|
||||
},
|
||||
element: document.getElementById('purpose-details-container')
|
||||
},
|
||||
'other': {
|
||||
callback: function(value, element) {
|
||||
callback: function(value, element, event) {
|
||||
// Only clear errors if this is a user-initiated event (not initial page load)
|
||||
if (!isInitialLoad) {
|
||||
clearErrors(element);
|
||||
}
|
||||
|
||||
// Show the purpose details container
|
||||
showElement(element);
|
||||
// change just the text inside the em tag
|
||||
const labelElement = element.querySelector('.usa-label em');
|
||||
const labelElement = element.querySelector('p em');
|
||||
labelElement.innerHTML = 'Describe how this domain will be used. ' +
|
||||
'<span class="usa-label--required">*</span>';
|
||||
|
||||
// Mark that we're no longer in initial load
|
||||
isInitialLoad = false;
|
||||
},
|
||||
element: document.getElementById('purpose-details-container')
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to clear error messages in a textarea
|
||||
function clearErrors(element) {
|
||||
// Find the error message div
|
||||
const errorMessage = element.querySelector('#id_purpose-purpose__error-message');
|
||||
if (errorMessage) {
|
||||
errorMessage.remove();
|
||||
}
|
||||
|
||||
// Find the form group and remove error class
|
||||
const formGroup = element.querySelector('.usa-form-group');
|
||||
if (formGroup) {
|
||||
formGroup.classList.remove('usa-form-group--error');
|
||||
}
|
||||
|
||||
// Find the textarea and remove error class
|
||||
const textarea = element.querySelector('#id_purpose-purpose');
|
||||
if (textarea) {
|
||||
textarea.classList.remove('usa-input--error');
|
||||
|
||||
// Also update aria attributes
|
||||
textarea.setAttribute('aria-invalid', 'false');
|
||||
|
||||
// Remove error message from aria-describedby
|
||||
const describedBy = textarea.getAttribute('aria-describedby');
|
||||
if (describedBy) {
|
||||
const newDescribedBy = describedBy.replace('id_purpose-purpose__error-message', '').trim();
|
||||
textarea.setAttribute('aria-describedby', newDescribedBy);
|
||||
}
|
||||
}
|
||||
|
||||
// Find the label and remove error class
|
||||
const label = element.querySelector('label');
|
||||
if (label) {
|
||||
label.classList.remove('usa-label--error');
|
||||
}
|
||||
}
|
|
@ -22,6 +22,13 @@ class UserFixture:
|
|||
"""
|
||||
|
||||
ADMINS = [
|
||||
{
|
||||
"username": "4aa78480-6272-42f9-ac29-a034ebdd9231",
|
||||
"first_name": "Kaitlin",
|
||||
"last_name": "Abbitt",
|
||||
"email": "kaitlin.abbitt@cisa.dhs.gov",
|
||||
"title": "Captain pirate",
|
||||
},
|
||||
{
|
||||
"username": "aad084c3-66cc-4632-80eb-41cdf5c5bcbf",
|
||||
"first_name": "Aditi",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from django import forms
|
||||
from django.core.validators import MaxLengthValidator
|
||||
from registrar.forms.utility.wizard_form_helper import BaseDeletableRegistrarForm, BaseYesNoForm
|
||||
from registrar.models.domain_request import DomainRequest
|
||||
|
||||
|
||||
class ExecutiveNamingRequirementsYesNoForm(BaseYesNoForm, BaseDeletableRegistrarForm):
|
||||
|
@ -11,6 +12,8 @@ class ExecutiveNamingRequirementsYesNoForm(BaseYesNoForm, BaseDeletableRegistrar
|
|||
|
||||
field_name = "feb_naming_requirements"
|
||||
|
||||
required_error_message = "Select “Yes” if your submission meets each domain naming requirement. Select “No” if it doesn’t meet each requirement." # noqa: E501
|
||||
|
||||
@property
|
||||
def form_is_checked(self):
|
||||
"""
|
||||
|
@ -25,7 +28,9 @@ class ExecutiveNamingRequirementsDetailsForm(BaseDeletableRegistrarForm):
|
|||
widget=forms.Textarea(attrs={"maxlength": "2000"}),
|
||||
max_length=2000,
|
||||
required=True,
|
||||
error_messages={"required": ("This field is required.")},
|
||||
error_messages={
|
||||
"required": ("Provide details on why your submission does not meet each domain naming requirement.")
|
||||
}, # noqa: E501
|
||||
validators=[
|
||||
MaxLengthValidator(
|
||||
2000,
|
||||
|
@ -41,18 +46,14 @@ class FEBPurposeOptionsForm(BaseDeletableRegistrarForm):
|
|||
|
||||
field_name = "feb_purpose_choice"
|
||||
|
||||
form_choices = (
|
||||
("new", "Used for a new website"),
|
||||
("redirect", "Used as a redirect for an existing website"),
|
||||
("other", "Not for a website"),
|
||||
)
|
||||
form_choices = DomainRequest.FEBPurposeChoices.choices
|
||||
|
||||
feb_purpose_choice = forms.ChoiceField(
|
||||
required=True,
|
||||
choices=form_choices,
|
||||
widget=forms.RadioSelect,
|
||||
error_messages={
|
||||
"required": "This question is required.",
|
||||
"required": "Select the purpose of your requested domain.",
|
||||
},
|
||||
label="Select one",
|
||||
)
|
||||
|
@ -65,6 +66,10 @@ class FEBTimeFrameYesNoForm(BaseDeletableRegistrarForm, BaseYesNoForm):
|
|||
"""
|
||||
|
||||
field_name = "has_timeframe"
|
||||
required_error_message = (
|
||||
"Select “Yes” if you have a target time frame for"
|
||||
" launching this domain. Select “No” if you don’t have a target time frame."
|
||||
)
|
||||
|
||||
@property
|
||||
def form_is_checked(self):
|
||||
|
@ -79,7 +84,7 @@ class FEBTimeFrameDetailsForm(BaseDeletableRegistrarForm):
|
|||
label="time_frame_details",
|
||||
widget=forms.Textarea(
|
||||
attrs={
|
||||
"aria-label": "Provide details on your target timeframe. \
|
||||
"aria-label": "Provide details on your target time frame. \
|
||||
Is there a special significance to this date (legal requirement, announcement, event, etc)?"
|
||||
}
|
||||
),
|
||||
|
@ -89,7 +94,7 @@ class FEBTimeFrameDetailsForm(BaseDeletableRegistrarForm):
|
|||
message="Response must be less than 2000 characters.",
|
||||
)
|
||||
],
|
||||
error_messages={"required": "Provide details on your target timeframe."},
|
||||
error_messages={"required": "Provide details on your target time frame."},
|
||||
)
|
||||
|
||||
|
||||
|
@ -100,6 +105,10 @@ class FEBInteragencyInitiativeYesNoForm(BaseDeletableRegistrarForm, BaseYesNoFor
|
|||
"""
|
||||
|
||||
field_name = "is_interagency_initiative"
|
||||
required_error_message = (
|
||||
"Select “Yes” if the domain will be used for an "
|
||||
"interagency initiative. Select “No” if it won’t be used for an interagency initiative."
|
||||
)
|
||||
|
||||
@property
|
||||
def form_is_checked(self):
|
||||
|
@ -156,29 +165,12 @@ class EOPContactForm(BaseDeletableRegistrarForm):
|
|||
error_messages={"required": "Enter the last name / family name of this contact."},
|
||||
required=True,
|
||||
)
|
||||
email = forms.EmailField(
|
||||
label="Email",
|
||||
max_length=None,
|
||||
error_messages={
|
||||
"required": ("Enter an email address in the required format, like name@example.com."),
|
||||
"invalid": ("Enter an email address in the required format, like name@example.com."),
|
||||
},
|
||||
validators=[
|
||||
MaxLengthValidator(
|
||||
320,
|
||||
message="Response must be less than 320 characters.",
|
||||
)
|
||||
],
|
||||
required=True,
|
||||
help_text="Enter an email address in the required format, like name@example.com.",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_database(cls, obj):
|
||||
return {
|
||||
"first_name": obj.eop_stakeholder_first_name,
|
||||
"last_name": obj.eop_stakeholder_last_name,
|
||||
"email": obj.eop_stakeholder_email,
|
||||
}
|
||||
|
||||
def to_database(self, obj):
|
||||
|
@ -192,7 +184,6 @@ class EOPContactForm(BaseDeletableRegistrarForm):
|
|||
return
|
||||
obj.eop_stakeholder_first_name = self.cleaned_data["first_name"]
|
||||
obj.eop_stakeholder_last_name = self.cleaned_data["last_name"]
|
||||
obj.eop_stakeholder_email = self.cleaned_data["email"]
|
||||
obj.save()
|
||||
|
||||
|
||||
|
|
|
@ -234,9 +234,12 @@ class BaseYesNoForm(RegistrarForm):
|
|||
# For instance, this could be "has_other_contacts"
|
||||
field_name: str
|
||||
|
||||
# This field can be overriden to show a custom error
|
||||
# message.
|
||||
required_error_message = "This question is required."
|
||||
|
||||
# Default form choice mapping. Default is suitable for most cases.
|
||||
# Override for more complex scenarios.
|
||||
form_choices = ((True, "Yes"), (False, "No"))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
|
|
@ -13,17 +13,17 @@ class Migration(migrations.Migration):
|
|||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
name="eop_stakeholder_email",
|
||||
field=models.EmailField(blank=True, max_length=254, null=True, verbose_name="EOP Stakeholder Email"),
|
||||
field=models.EmailField(blank=True, max_length=254, null=True, verbose_name="EOP contact email"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
name="eop_stakeholder_first_name",
|
||||
field=models.CharField(blank=True, null=True, verbose_name="EOP Stakeholder First Name"),
|
||||
field=models.CharField(blank=True, null=True, verbose_name="EOP contact first name"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
name="eop_stakeholder_last_name",
|
||||
field=models.CharField(blank=True, null=True, verbose_name="EOP Stakeholder Last Name"),
|
||||
field=models.CharField(blank=True, null=True, verbose_name="EOP contact last name"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="domainrequest",
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
# Generated by Django 4.2.20 on 2025-03-26 19:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("registrar", "0145_create_groups_v19"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name="domainrequest",
|
||||
name="eop_stakeholder_email",
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="domainrequest",
|
||||
name="feb_naming_requirements",
|
||||
field=models.BooleanField(blank=True, null=True, verbose_name="Meets naming requirements"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="domainrequest",
|
||||
name="feb_naming_requirements_details",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
help_text="Required if requested domain that doesn't meet naming requirements",
|
||||
null=True,
|
||||
verbose_name="Domain name rationale",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="domainrequest",
|
||||
name="feb_purpose_choice",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("new", "Used for a new website"),
|
||||
("redirect", "Used as a redirect for an existing website"),
|
||||
("other", "Not for a website"),
|
||||
],
|
||||
null=True,
|
||||
verbose_name="Purpose type",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="domainrequest",
|
||||
name="interagency_initiative_details",
|
||||
field=models.TextField(blank=True, null=True, verbose_name="Interagency initiative"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="domainrequest",
|
||||
name="time_frame_details",
|
||||
field=models.TextField(blank=True, null=True, verbose_name="Target time frame"),
|
||||
),
|
||||
]
|
|
@ -55,19 +55,14 @@ class DomainRequest(TimeStampedModel):
|
|||
return cls(status_name).label if status_name else None
|
||||
|
||||
class FEBPurposeChoices(models.TextChoices):
|
||||
WEBSITE = "website"
|
||||
REDIRECT = "redirect"
|
||||
OTHER = "other"
|
||||
WEBSITE = "new", "Used for a new website"
|
||||
REDIRECT = "redirect", "Used as a redirect for an existing website"
|
||||
OTHER = "other", "Not for a website"
|
||||
|
||||
@classmethod
|
||||
def get_purpose_label(cls, purpose_name: str):
|
||||
def get_purpose_label(cls, purpose_name: str | None):
|
||||
"""Returns the associated label for a given purpose name"""
|
||||
if purpose_name == cls.WEBSITE:
|
||||
return "Used for a new website"
|
||||
elif purpose_name == cls.REDIRECT:
|
||||
return "Used as a redirect for an existing website"
|
||||
else:
|
||||
return "Not for a website"
|
||||
return cls(purpose_name).label if purpose_name else None
|
||||
|
||||
class StateTerritoryChoices(models.TextChoices):
|
||||
ALABAMA = "AL", "Alabama (AL)"
|
||||
|
@ -520,6 +515,7 @@ class DomainRequest(TimeStampedModel):
|
|||
feb_naming_requirements = models.BooleanField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="Meets naming requirements",
|
||||
)
|
||||
|
||||
feb_naming_requirements_details = models.TextField(
|
||||
|
@ -544,19 +540,13 @@ class DomainRequest(TimeStampedModel):
|
|||
eop_stakeholder_first_name = models.CharField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="EOP Stakeholder First Name",
|
||||
verbose_name="EOP contact first name",
|
||||
)
|
||||
|
||||
eop_stakeholder_last_name = models.CharField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="EOP Stakeholder Last Name",
|
||||
)
|
||||
|
||||
eop_stakeholder_email = models.EmailField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="EOP Stakeholder Email",
|
||||
verbose_name="EOP contact last name",
|
||||
)
|
||||
|
||||
# This field is alternately used for generic domain purpose explanations
|
||||
|
@ -1030,12 +1020,14 @@ class DomainRequest(TimeStampedModel):
|
|||
has_organization_feature_flag = flag_is_active_for_user(recipient, "organization_feature")
|
||||
is_org_user = has_organization_feature_flag and recipient.has_view_portfolio_permission(self.portfolio)
|
||||
requires_feb_questions = self.is_feb() and is_org_user
|
||||
purpose_label = DomainRequest.FEBPurposeChoices.get_purpose_label(self.feb_purpose_choice)
|
||||
context = {
|
||||
"domain_request": self,
|
||||
# This is the user that we refer to in the email
|
||||
"recipient": recipient,
|
||||
"is_org_user": is_org_user,
|
||||
"requires_feb_questions": requires_feb_questions,
|
||||
"purpose_label": purpose_label,
|
||||
}
|
||||
|
||||
if custom_email_content:
|
||||
|
|
|
@ -2,19 +2,25 @@
|
|||
{% 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="{% if requires_feb_questions %}https://get.gov/domains/executive-branch-guidance/{% else %}{% public_site_url 'domains/choosing' %}{% endif %}">our naming requirements</a>. Your domain name must:
|
||||
<p>
|
||||
Before requesting a .gov domain, please make sure it meets
|
||||
{% if requires_feb_questions %}
|
||||
<a class="usa-link" rel="noopener noreferrer" target="_blank" href="https://get.gov/domains/executive-branch-guidance/">our naming requirements for executive branch agencies</a>. Your domain name must:
|
||||
{% else %}
|
||||
<a class="usa-link" rel="noopener noreferrer" target="_blank" href="{% public_site_url 'domains/choosing' %}">our naming requirements</a>. Your domain name must:
|
||||
{% endif %}
|
||||
<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
|
||||
|
@ -29,7 +35,7 @@
|
|||
|
||||
|
||||
{% block form_required_fields_help_text %}
|
||||
{# empty this block so it doesn't show on this page #}
|
||||
{# empty this block so it doesn’t show on this page #}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
@ -42,8 +48,8 @@
|
|||
<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.
|
||||
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 #}
|
||||
|
@ -65,7 +71,7 @@
|
|||
<h2 id="alternative-domains-title">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?
|
||||
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 #}
|
||||
|
@ -99,7 +105,7 @@
|
|||
>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.
|
||||
If you’re not sure this is the domain you want, that’s ok. You can change the domain later.
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
|
@ -114,9 +120,10 @@
|
|||
<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.
|
||||
naming requirements for executive branch agencies.</a> Agency submissions are expected to meet each requirement.
|
||||
</p>
|
||||
<p class="usa-label margin-top-0 margin-bottom-0">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.2.feb_naming_requirements %}
|
||||
|
@ -124,13 +131,12 @@
|
|||
|
||||
{# 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 class="margin-bottom-3 margin-top-3">
|
||||
<em>Provide details below. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</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 %}
|
||||
|
|
|
@ -12,14 +12,12 @@
|
|||
|
||||
{% block form_fields %}
|
||||
{% if requires_feb_questions %}
|
||||
<fieldset class="usa-fieldset margin-top-0 dotgov-domain-form">
|
||||
<fieldset class="usa-fieldset margin-top-0">
|
||||
{{forms.0.management_form}}
|
||||
{{forms.1.management_form}}
|
||||
{{forms.2.management_form}}
|
||||
{{forms.3.management_form}}
|
||||
{{forms.4.management_form}}
|
||||
{{forms.5.management_form}}
|
||||
<h2>What is the purpose of your requested domain?</h2>
|
||||
<legend>
|
||||
<h2>What is the purpose of your requested domain?</h2>
|
||||
</legend>
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
|
@ -28,51 +26,58 @@
|
|||
{% endwith %}
|
||||
|
||||
<div id="purpose-details-container" class="conditional-panel display-none">
|
||||
<p class="usa-label">
|
||||
<em>Provide details below <span class="usa-label--required">*</span></em>
|
||||
<p class="margin-bottom-3 margin-top-3">
|
||||
<em>Provide details below. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_label_class="usa-sr-only" attr_required="required" attr_maxlength="2000" %}
|
||||
{% input_with_errors forms.1.purpose %}
|
||||
{% endwith %}
|
||||
<p class="usa-hint margin-top-0">Maximum 2000 characters allowed.</p>
|
||||
</div>
|
||||
|
||||
<h2>Do you have a target time frame for launching this domain?</h2>
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.2.has_timeframe %}
|
||||
{% endwith %}
|
||||
|
||||
<div id="purpose-timeframe-details-container" class="conditional-panel">
|
||||
</fieldset>
|
||||
<fieldset class="usa-fieldset margin-top-2">
|
||||
{{forms.2.management_form}}
|
||||
{{forms.3.management_form}}
|
||||
<legend>
|
||||
<h2>Do you have a target time frame for launching this domain?</h2>
|
||||
</legend>
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Provide details below. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_label_class="usa-sr-only" attr_required="required" attr_maxlength="2000" %}
|
||||
{% input_with_errors forms.3.time_frame_details %}
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.2.has_timeframe %}
|
||||
{% endwith %}
|
||||
<p class="usa-hint margin-top-0">Maximum 2000 characters allowed.</p>
|
||||
</div>
|
||||
|
||||
<h2>Will the domain name be used for an interagency initiative?</h2>
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.4.is_interagency_initiative %}
|
||||
{% endwith %}
|
||||
|
||||
<div id="purpose-interagency-initaitive-details-container" class="conditional-panel">
|
||||
<div id="purpose-timeframe-details-container" class="conditional-panel">
|
||||
<p class="margin-bottom-3 margin-top-3">
|
||||
<em>Provide details on your target time frame. Is there special significance of this day (legal requirement, announcement, event, etc.)? <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_label_class="usa-sr-only" attr_required="required" attr_maxlength="2000" %}
|
||||
{% input_with_errors forms.3.time_frame_details %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="usa-fieldset margin-top-2" aria-labelledby="interagency-initiative-question">
|
||||
{{forms.4.management_form}}
|
||||
{{forms.5.management_form}}
|
||||
<legend>
|
||||
<h2 id="interagency-initiative-question">Will the domain name be used for an interagency initiative?</h2>
|
||||
</legend>
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Provide details below. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_label_class="usa-sr-only" attr_required="required" attr_maxlength="2000" %}
|
||||
{% input_with_errors forms.5.interagency_initiative_details %}
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.4.is_interagency_initiative %}
|
||||
{% endwith %}
|
||||
<p class="usa-hint margin-top-0">Maximum 2000 characters allowed.</p>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div id="purpose-interagency-initaitive-details-container" class="conditional-panel">
|
||||
<p class="margin-bottom-3 margin-top-3">
|
||||
<em>Name the agencies that will be involved in this initiative. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_label_class="usa-sr-only" attr_required="required" attr_maxlength="2000" %}
|
||||
{% input_with_errors forms.5.interagency_initiative_details %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</fieldset>
|
||||
{% else %}
|
||||
<h2>What is the purpose of your requested domain?</h2>
|
||||
<p>Describe how you’ll use your .gov domain. Will it be used for a website, email, or something else?</p>
|
||||
|
|
|
@ -41,6 +41,7 @@ Alternative domains:
|
|||
{% endfor %}{% endif %}
|
||||
Purpose of your domain:
|
||||
{{ domain_request.purpose }}
|
||||
|
||||
Your contact information:
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=recipient %}{% endspaceless %}
|
||||
|
||||
|
@ -48,8 +49,7 @@ Other employees from your organization:{% for other in domain_request.other_cont
|
|||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=other %}{% endspaceless %}
|
||||
{% empty %}
|
||||
{{ domain_request.no_other_contacts_rationale }}
|
||||
{% endfor %}
|
||||
{% if domain_request.anything_else %}
|
||||
Anything else?
|
||||
{{ domain_request.anything_else }}
|
||||
{% endfor %}{% if domain_request.anything_else %}
|
||||
Anything else?
|
||||
{{ domain_request.anything_else }}
|
||||
{% endif %}
|
|
@ -9,7 +9,7 @@ Current websites: {% for site in domain_request.current_websites.all %}
|
|||
.gov domain:
|
||||
{{ domain_request.requested_domain.name }}
|
||||
{% if requires_feb_questions %}
|
||||
Meets Naming Requirements
|
||||
Meets naming requirements
|
||||
{% if domain_request.feb_naming_requirements %}
|
||||
{{ domain_request.feb_naming_requirements }}
|
||||
{% else %}
|
||||
|
@ -23,7 +23,7 @@ Alternative domains:
|
|||
{% endfor %}{% endif %}
|
||||
Purpose of your domain:
|
||||
{% if requires_feb_questions %}
|
||||
{{ domain_request.feb_purpose_choice }}
|
||||
{{ purpose_label }}
|
||||
{{ domain_request.purpose }}
|
||||
Target time frame:
|
||||
{% if domain_request.has_target_time_frame %}
|
||||
|
@ -41,7 +41,7 @@ No
|
|||
{{ domain_request.purpose }}
|
||||
{% endif %}
|
||||
{% if requires_feb_questions %}
|
||||
EOP Stakeholder:
|
||||
EOP contact:
|
||||
{% if domain_request.working_with_eop %}
|
||||
{{ domain_request.eop_contact.first_name }} {{ domain_request.eop_contact.last_name }}
|
||||
{{ domain_request.eop_contact.email }}
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
</ul>
|
||||
{% endif %}
|
||||
{% if requires_feb_questions %}
|
||||
<h4 class="margin-bottom-0">Meets Naming Requirements</h4>
|
||||
<h4 class="margin-bottom-0">Meets naming requirements</h4>
|
||||
{% if domain_request.feb_naming_requirements is None %}
|
||||
<p class="margin-y-0"><span class='text-bold text-secondary-dark'>Incomplete</span></p>
|
||||
{% elif domain_request.feb_naming_requirements %}
|
||||
|
@ -67,24 +67,18 @@
|
|||
{% endif %}
|
||||
|
||||
{% if step == Step.PURPOSE %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.purpose|default:"<span class='text-bold text-secondary-dark'>Incomplete</span>"|safe %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=is_editable edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% if requires_feb_questions %}
|
||||
{% with title=form_titles|get_item:step %}
|
||||
{% include "includes/summary_item.html" with title=title value=" " heading_level=heading_level editable=is_editable edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
<h4 class="margin-bottom-0">Purpose</h4>
|
||||
{% if domain_request.feb_purpose_choice == "website" %}
|
||||
<p class="margin-y-0">Used for a new website</p>
|
||||
<p class="margin-y-0">{{domain_request.purpose}}</p>
|
||||
{% elif domain_request.feb_purpose_choice == "redirect" %}
|
||||
<p class="margin-y-0">Used as a redirect for an existing website</p>
|
||||
<p class="margin-y-0">{{domain_request.purpose}}</p>
|
||||
{% elif domain_request.feb_purpose_choice == "other" %}
|
||||
<p class="margin-y-0">Not for a website</p>
|
||||
{% if domain_request.feb_purpose_choice %}
|
||||
<p class="margin-y-0">{{purpose_label}}</p>
|
||||
<p class="margin-y-0">{{domain_request.purpose}}</p>
|
||||
{% else %}
|
||||
<p class="margin-y-0"><span class='text-bold text-secondary-dark'>Incomplete</span></p>
|
||||
{% endif %}
|
||||
<h4 class="margin-bottom-0">Target Time Frame</h4>
|
||||
<h4 class="margin-bottom-0">Target time frame</h4>
|
||||
{% if domain_request.has_timeframe is None %}
|
||||
<p class="margin-y-0"><span class='text-bold text-secondary-dark'>Incomplete</span></p>
|
||||
{% elif domain_request.has_timeframe %}
|
||||
|
@ -92,7 +86,7 @@
|
|||
{% else %}
|
||||
<p class="margin-y-0">No</p>
|
||||
{% endif %}
|
||||
<h4 class="margin-bottom-0">Interagency Initiative</h4>
|
||||
<h4 class="margin-bottom-0">Interagency initiative</h4>
|
||||
{% if domain_request.is_interagency_initiative is None %}
|
||||
<p class="margin-y-0"><span class='text-bold text-secondary-dark'>Incomplete</span></p>
|
||||
{% elif domain_request.is_interagency_initiative %}
|
||||
|
@ -100,23 +94,36 @@
|
|||
{% else %}
|
||||
<p class="margin-y-0">No</p>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.purpose|default:"<span class='text-bold text-secondary-dark'>Incomplete</span>"|safe %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=is_editable edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.ADDITIONAL_DETAILS %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.anything_else|default:"None" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=is_editable edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% if requires_feb_questions %}
|
||||
<h4 class="margin-bottom-0">EOP Stakeholder</h4>
|
||||
{% with title=form_titles|get_item:step %}
|
||||
{% include "includes/summary_item.html" with title=title value=" " heading_level=heading_level editable=is_editable edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
<h4 class="margin-bottom-0">EOP contact</h4>
|
||||
{% if domain_request.working_with_eop is None %}
|
||||
<p class="margin-y-0"><span class='text-bold text-secondary-dark'>Incomplete</span></p>
|
||||
{% elif domain_request.working_with_eop %}
|
||||
<p class="margin-y-0">{{domain_request.eop_stakeholder_first_name}} {{domain_request.eop_stakeholder_last_name}}</p>
|
||||
<p class="margin-y-0">{{domain_request.eop_stakeholder_email}}</p>
|
||||
{% else %}
|
||||
<p class="margin-y-0">No</p>
|
||||
{% endif %}
|
||||
<h4 class="margin-bottom-0">Anything else</h4>
|
||||
{% if domain_request.anything_else %}
|
||||
<p class="margin-y-0">{{domain_request.anything_else}}</p>
|
||||
{% else %}
|
||||
<p class="margin-y-0">None</p>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.anything_else|default:"None" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=is_editable edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
|
|
@ -6,60 +6,62 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block form_fields %}
|
||||
{% if requires_feb_questions %}
|
||||
{% include "includes/required_fields.html" %}
|
||||
{% if requires_feb_questions %}
|
||||
<fieldset class="usa-fieldset">
|
||||
{{forms.0.management_form}}
|
||||
{{forms.1.management_form}}
|
||||
<h2 id="working-with-eop--question" class="margin-top-0 margin-bottom-0">Are you working with someone in the Executive Office of the President (EOP) on this request?</h2>
|
||||
<p id="working-with-eop--requirement" class="margin-bottom-2 margin-top-2">Working with the EOP is not required to request a .gov domain.</p>
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" add_aria_describedby="working-with-eop--requirement" add_legend_heading="Are you working with someone in the Executive Office of the President (EOP) on this request?" %}
|
||||
{% input_with_errors forms.0.working_with_eop %}
|
||||
{% endwith %}
|
||||
|
||||
<div id="eop-contact-container" class="conditional-panel display-none">
|
||||
<p class="margin-bottom-3 margin-top-3">
|
||||
<em>Provide the name of the person you're working with. <span class="usa-label--required">*</span></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.1.first_name %}
|
||||
{% input_with_errors forms.1.last_name %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="usa-fieldset" aria-labelledby="anything-else-question">
|
||||
{{forms.2.management_form}}
|
||||
{{forms.3.management_form}}
|
||||
{{forms.4.management_form}}
|
||||
{{forms.5.management_form}}
|
||||
<fieldset class="usa-fieldset">
|
||||
<h2 class="margin-top-0 margin-bottom-0">Are you working with someone in the Executive Office of the President (EOP) on this request?</h2>
|
||||
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.0.working_with_eop %}
|
||||
{% endwith %}
|
||||
<h2 id="anything-else-question">Is there anything else you'd like us to know about your domain request?</h2>
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" add_legend_heading="Is there anything else you'd like us to know about your domain request?"%}
|
||||
{% input_with_errors forms.2.has_anything_else_text %}
|
||||
{% endwith %}
|
||||
|
||||
<div id="eop-contact-container" class="conditional-panel display-none">
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
Provide the name and email of the person you're working with.<span class="usa-label--required">*</span>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.1.first_name %}
|
||||
{% input_with_errors forms.1.last_name %}
|
||||
{% input_with_errors forms.1.email %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
<h2 class="margin-top-0 margin-bottom-0">Is there anything else you'd like us to know about your domain request?</h2>
|
||||
<p class="margin-bottom-0 margin-top-1">
|
||||
<em>Select one. <abbr class="usa-hint usa-hint--required" title="required">*</abbr></em>
|
||||
</p>
|
||||
{% with add_class="usa-radio__input--tile" add_legend_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.2.has_anything_else_text %}
|
||||
{% endwith %}
|
||||
|
||||
<div id="anything-else-details-container" class="conditional-panel display-none">
|
||||
<p class="usa-label">
|
||||
<em>Provide details below <span class="usa-label--required">*</span></em>
|
||||
</p>
|
||||
{% with add_label_class="usa-sr-only" attr_required="required" attr_maxlength="2000" %}
|
||||
{% input_with_errors forms.3.anything_else %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</fieldset>
|
||||
{% else %}
|
||||
<fieldset class="usa-fieldset">
|
||||
<h2 class="margin-top-0 margin-bottom-0">Is there anything else you’d like us to know about your domain request?</h2>
|
||||
</legend>
|
||||
</fieldset>
|
||||
|
||||
<div id="anything-else">
|
||||
<p><em>This question is optional.</em></p>
|
||||
{% with attr_maxlength=2000 add_label_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.0.anything_else %}
|
||||
{% endwith %}
|
||||
<div id="anything-else-details-container" class="conditional-panel display-none">
|
||||
<p class="margin-bottom-3 margin-top-3">
|
||||
<em>Provide details below. <span class="usa-label--required">*</span></em>
|
||||
</p>
|
||||
{% with add_label_class="usa-sr-only" attr_required="required" attr_maxlength="2000" %}
|
||||
{% input_with_errors forms.3.anything_else %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
{% else %}
|
||||
<fieldset class="usa-fieldset" aria-labelledby="anything-else-question">
|
||||
<h2 id="anything-else-question" class="margin-top-0 margin-bottom-0">Is there anything else you’d like us to know about your domain request?</h2>
|
||||
</legend>
|
||||
</fieldset>
|
||||
|
||||
<div id="anything-else">
|
||||
<p><em>This question is optional.</em></p>
|
||||
{% with attr_maxlength=2000 add_label_class="usa-sr-only" %}
|
||||
{% input_with_errors forms.3.anything_else %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -23,8 +23,10 @@ def input_with_errors(context, field=None): # noqa: C901
|
|||
add_required_class: like `add_class` but only if field is required
|
||||
add_label_class: append to input element's label's `class` attribute
|
||||
add_legend_class: append to input element's legend's `class` attribute
|
||||
add_legend_heading: sets the text for the legend associated with this element
|
||||
add_group_class: append to input element's surrounding tag's `class` attribute
|
||||
add_aria_label: append to input element's `aria_label` attribute
|
||||
add_aria_describedby: appends to input element's `aria-describedby` attribute
|
||||
attr_* - adds or replaces any single html attribute for the input
|
||||
add_error_attr_* - like `attr_*` but only if field.errors is not empty
|
||||
toggleable_input: shows a simple edit button, and adds display-none to the input field.
|
||||
|
@ -106,6 +108,8 @@ def input_with_errors(context, field=None): # noqa: C901
|
|||
|
||||
elif key == "add_aria_label":
|
||||
aria_labels.append(value)
|
||||
elif key == "add_aria_describedby":
|
||||
described_by.append(value)
|
||||
|
||||
elif key == "sublabel_text":
|
||||
sublabel_text.append(value)
|
||||
|
|
|
@ -2064,7 +2064,6 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"working_with_eop",
|
||||
"eop_stakeholder_first_name",
|
||||
"eop_stakeholder_last_name",
|
||||
"eop_stakeholder_email",
|
||||
"purpose",
|
||||
"has_timeframe",
|
||||
"time_frame_details",
|
||||
|
|
|
@ -2648,7 +2648,6 @@ class DomainRequestTests(TestWithUser, WebTest):
|
|||
additional_details_form["portfolio_additional_details-working_with_eop"] = "True"
|
||||
additional_details_form["portfolio_additional_details-first_name"] = "TesterFirstName"
|
||||
additional_details_form["portfolio_additional_details-last_name"] = "TesterLastName"
|
||||
additional_details_form["portfolio_additional_details-email"] = "testy@town.com"
|
||||
additional_details_form["portfolio_additional_details-has_anything_else_text"] = "True"
|
||||
additional_details_form["portfolio_additional_details-anything_else"] = "test"
|
||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||
|
@ -2720,7 +2719,6 @@ class DomainRequestTests(TestWithUser, WebTest):
|
|||
self.assertContains(additional_details_page, "eop-contact-container")
|
||||
self.assertContains(additional_details_page, "additional_details-first_name")
|
||||
self.assertContains(additional_details_page, "additional_details-last_name")
|
||||
self.assertContains(additional_details_page, "additional_details-email")
|
||||
|
||||
# Make sure the additional details form is present
|
||||
self.assertContains(additional_details_page, "additional_details-has_anything_else_text")
|
||||
|
@ -2744,24 +2742,23 @@ class DomainRequestTests(TestWithUser, WebTest):
|
|||
)
|
||||
|
||||
def feb_review_page_tests(self, review_page):
|
||||
# Meets Naming Requirements
|
||||
self.assertContains(review_page, "Meets Naming Requirements")
|
||||
# Meets naming requirements
|
||||
self.assertContains(review_page, "Meets naming requirements")
|
||||
self.assertContains(review_page, "No")
|
||||
self.assertContains(review_page, "Because this is a test")
|
||||
# Purpose
|
||||
self.assertContains(review_page, "Purpose")
|
||||
self.assertContains(review_page, "Used as a redirect for an existing website")
|
||||
self.assertContains(review_page, "testPurpose123")
|
||||
# Target Time Frame
|
||||
self.assertContains(review_page, "Target Time Frame")
|
||||
# Target time frame
|
||||
self.assertContains(review_page, "Target time frame")
|
||||
self.assertContains(review_page, "1/2/2025 - 1/2/2026")
|
||||
# Interagency Initiative
|
||||
self.assertContains(review_page, "Interagency Initiative")
|
||||
# Interagency initiative
|
||||
self.assertContains(review_page, "Interagency initiative")
|
||||
self.assertContains(review_page, "FakeInteragencyInitiative")
|
||||
# EOP Stakeholder
|
||||
self.assertContains(review_page, "EOP Stakeholder")
|
||||
# EOP contact
|
||||
self.assertContains(review_page, "EOP contact")
|
||||
self.assertContains(review_page, "TesterFirstName TesterLastName")
|
||||
self.assertContains(review_page, "testy@town.com")
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_domain_request_formsets(self):
|
||||
|
|
|
@ -1900,7 +1900,6 @@ class DomainRequestExport(BaseExport):
|
|||
"Target time frame": model.get("time_frame_details", None),
|
||||
"Interagency initiative": model.get("interagency_initiative_details", None),
|
||||
"EOP stakeholder name": eop_stakeholder_name,
|
||||
"EOP stakeholder email": model.get("eop_stakeholder_email", None),
|
||||
}
|
||||
|
||||
row = [FIELDS.get(column, "") for column in columns]
|
||||
|
|
|
@ -625,6 +625,11 @@ class PortfolioAdditionalDetails(DomainRequestWizard):
|
|||
2: FEBAnythingElseYesNoForm
|
||||
3: PortfolioAnythingElseForm
|
||||
"""
|
||||
if not self.requires_feb_questions():
|
||||
for i in range(3):
|
||||
forms[i].mark_form_for_deletion()
|
||||
# If FEB questions aren't required, validate only the anything else form
|
||||
return forms[3].is_valid()
|
||||
eop_forms_valid = True
|
||||
if not forms[0].is_valid():
|
||||
# If the user isn't working with EOP, don't validate the EOP contact form
|
||||
|
@ -792,11 +797,11 @@ class Purpose(DomainRequestWizard):
|
|||
option = feb_purpose_options_form.cleaned_data.get("feb_purpose_choice")
|
||||
if option == "new":
|
||||
purpose_details_form.fields["purpose"].error_messages = {
|
||||
"required": "Explain why a new domain is required."
|
||||
"required": "Provide details on why a new domain is required."
|
||||
}
|
||||
elif option == "redirect":
|
||||
purpose_details_form.fields["purpose"].error_messages = {
|
||||
"required": "Explain why a redirect is needed."
|
||||
"required": "Provide details on why a redirect is necessary."
|
||||
}
|
||||
elif option == "other":
|
||||
purpose_details_form.fields["purpose"].error_messages = {
|
||||
|
@ -965,6 +970,9 @@ class Review(DomainRequestWizard):
|
|||
context["Step"] = self.get_step_enum().__members__
|
||||
context["domain_request"] = self.domain_request
|
||||
context["requires_feb_questions"] = self.requires_feb_questions()
|
||||
context["purpose_label"] = DomainRequest.FEBPurposeChoices.get_purpose_label(
|
||||
self.domain_request.feb_purpose_choice
|
||||
)
|
||||
return context
|
||||
|
||||
def goto_next_step(self):
|
||||
|
@ -1178,11 +1186,10 @@ class PortfolioDomainRequestStatusViewOnly(DetailView):
|
|||
context["Step"] = PortfolioDomainRequestStep.__members__
|
||||
context["steps"] = request_step_list(wizard, PortfolioDomainRequestStep)
|
||||
context["form_titles"] = wizard.titles
|
||||
logger.debug(self.object.is_feb())
|
||||
logger.debug(flag_is_active_for_user(self.request.user, "organization_feature"))
|
||||
context["requires_feb_questions"] = self.object.is_feb() and flag_is_active_for_user(
|
||||
self.request.user, "organization_feature"
|
||||
)
|
||||
context["purpose_label"] = DomainRequest.FEBPurposeChoices.get_purpose_label(self.object.feb_purpose_choice)
|
||||
return context
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue