mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-13 04:59:59 +02:00
Merge branch 'main' into za/additional-data-transferred-domains
This commit is contained in:
commit
353079e7dd
6 changed files with 135 additions and 53 deletions
|
@ -273,31 +273,35 @@ function prepareDeleteButtons(formLabel) {
|
||||||
// h2 and legend for DS form, label for nameservers
|
// h2 and legend for DS form, label for nameservers
|
||||||
Array.from(form.querySelectorAll('h2, legend, label, p')).forEach((node) => {
|
Array.from(form.querySelectorAll('h2, legend, label, p')).forEach((node) => {
|
||||||
|
|
||||||
// Ticket: 1192
|
// If the node is a nameserver label, one of the first 2 which was previously 3 and up (not required)
|
||||||
// if (isNameserversForm && index <= 1 && !node.innerHTML.includes('*')) {
|
// inject the USWDS required markup and make sure the INPUT is required
|
||||||
// // Create a new element
|
if (isNameserversForm && index <= 1 && node.innerHTML.includes('server') && !node.innerHTML.includes('*')) {
|
||||||
// const newElement = document.createElement('abbr');
|
// Create a new element
|
||||||
// newElement.textContent = '*';
|
const newElement = document.createElement('abbr');
|
||||||
// // TODO: finish building abbr
|
newElement.textContent = '*';
|
||||||
|
newElement.setAttribute("title", "required");
|
||||||
|
newElement.classList.add("usa-hint", "usa-hint--required");
|
||||||
|
|
||||||
// // Append the new element to the parent
|
// Append the new element to the label
|
||||||
// node.appendChild(newElement);
|
node.appendChild(newElement);
|
||||||
// // Find the next sibling that is an input element
|
// Find the next sibling that is an input element
|
||||||
// let nextInputElement = node.nextElementSibling;
|
let nextInputElement = node.nextElementSibling;
|
||||||
|
|
||||||
// while (nextInputElement) {
|
while (nextInputElement) {
|
||||||
// if (nextInputElement.tagName === 'INPUT') {
|
if (nextInputElement.tagName === 'INPUT') {
|
||||||
// // Found the next input element
|
// Found the next input element
|
||||||
// console.log(nextInputElement);
|
nextInputElement.setAttribute("required", "")
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// nextInputElement = nextInputElement.nextElementSibling;
|
nextInputElement = nextInputElement.nextElementSibling;
|
||||||
// }
|
}
|
||||||
// nextInputElement.required = true;
|
nextInputElement.required = true;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Ticket: 1192 - remove if
|
let innerSpan = node.querySelector('span')
|
||||||
if (!(isNameserversForm && index <= 1)) {
|
if (innerSpan) {
|
||||||
|
innerSpan.textContent = innerSpan.textContent.replace(formLabelRegex, `${formLabel} ${index + 1}`);
|
||||||
|
} else {
|
||||||
node.textContent = node.textContent.replace(formLabelRegex, `${formLabel} ${index + 1}`);
|
node.textContent = node.textContent.replace(formLabelRegex, `${formLabel} ${index + 1}`);
|
||||||
node.textContent = node.textContent.replace(formExampleRegex, `ns${index + 1}`);
|
node.textContent = node.textContent.replace(formExampleRegex, `ns${index + 1}`);
|
||||||
}
|
}
|
||||||
|
@ -305,7 +309,15 @@ function prepareDeleteButtons(formLabel) {
|
||||||
|
|
||||||
// Display the add more button if we have less than 13 forms
|
// Display the add more button if we have less than 13 forms
|
||||||
if (isNameserversForm && forms.length <= 13) {
|
if (isNameserversForm && forms.length <= 13) {
|
||||||
addButton.classList.remove("display-none")
|
console.log('remove disabled');
|
||||||
|
addButton.removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNameserversForm && forms.length < 3) {
|
||||||
|
// Hide the delete buttons on the remaining nameservers
|
||||||
|
Array.from(form.querySelectorAll('.delete-record')).forEach((deleteButton) => {
|
||||||
|
deleteButton.setAttribute("disabled", "true");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -333,6 +345,11 @@ function prepareDeleteButtons(formLabel) {
|
||||||
formLabel = "DS Data record";
|
formLabel = "DS Data record";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On load: Disable the add more button if we have 13 forms
|
||||||
|
if (isNameserversForm && document.querySelectorAll(".repeatable-form").length == 13) {
|
||||||
|
addButton.setAttribute("disabled", "true");
|
||||||
|
}
|
||||||
|
|
||||||
// Attach click event listener on the delete buttons of the existing forms
|
// Attach click event listener on the delete buttons of the existing forms
|
||||||
prepareDeleteButtons(formLabel);
|
prepareDeleteButtons(formLabel);
|
||||||
|
|
||||||
|
@ -348,6 +365,33 @@ function prepareDeleteButtons(formLabel) {
|
||||||
// For the eample on Nameservers
|
// For the eample on Nameservers
|
||||||
let formExampleRegex = RegExp(`ns(\\d){1}`, 'g');
|
let formExampleRegex = RegExp(`ns(\\d){1}`, 'g');
|
||||||
|
|
||||||
|
// Some Nameserver form checks since the delete can mess up the source object we're copying
|
||||||
|
// in regards to required fields and hidden delete buttons
|
||||||
|
if (isNameserversForm) {
|
||||||
|
|
||||||
|
// If the source element we're copying has required on an input,
|
||||||
|
// reset that input
|
||||||
|
let formRequiredNeedsCleanUp = newForm.innerHTML.includes('*');
|
||||||
|
if (formRequiredNeedsCleanUp) {
|
||||||
|
newForm.querySelector('label abbr').remove();
|
||||||
|
// Get all input elements within the container
|
||||||
|
const inputElements = newForm.querySelectorAll("input");
|
||||||
|
// Loop through each input element and remove the 'required' attribute
|
||||||
|
inputElements.forEach((input) => {
|
||||||
|
if (input.hasAttribute("required")) {
|
||||||
|
input.removeAttribute("required");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the source element we're copying has an disabled delete button,
|
||||||
|
// enable that button
|
||||||
|
let deleteButton= newForm.querySelector('.delete-record');
|
||||||
|
if (deleteButton.hasAttribute("disabled")) {
|
||||||
|
deleteButton.removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
formNum++;
|
formNum++;
|
||||||
newForm.innerHTML = newForm.innerHTML.replace(formNumberRegex, `form-${formNum-1}-`);
|
newForm.innerHTML = newForm.innerHTML.replace(formNumberRegex, `form-${formNum-1}-`);
|
||||||
newForm.innerHTML = newForm.innerHTML.replace(formLabelRegex, `${formLabel} ${formNum}`);
|
newForm.innerHTML = newForm.innerHTML.replace(formLabelRegex, `${formLabel} ${formNum}`);
|
||||||
|
@ -397,9 +441,18 @@ function prepareDeleteButtons(formLabel) {
|
||||||
// Attach click event listener on the delete buttons of the new form
|
// Attach click event listener on the delete buttons of the new form
|
||||||
prepareDeleteButtons(formLabel);
|
prepareDeleteButtons(formLabel);
|
||||||
|
|
||||||
// Hide the add more button if we have 13 forms
|
// Disable the add more button if we have 13 forms
|
||||||
if (isNameserversForm && formNum == 13) {
|
if (isNameserversForm && formNum == 13) {
|
||||||
addButton.classList.add("display-none")
|
addButton.setAttribute("disabled", "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNameserversForm && forms.length >= 2) {
|
||||||
|
// Enable the delete buttons on the nameservers
|
||||||
|
forms.forEach((form, index) => {
|
||||||
|
Array.from(form.querySelectorAll('.delete-record')).forEach((deleteButton) => {
|
||||||
|
deleteButton.removeAttribute("disabled");
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -23,11 +23,6 @@ class DomainAddUserForm(forms.Form):
|
||||||
email = forms.EmailField(label="Email")
|
email = forms.EmailField(label="Email")
|
||||||
|
|
||||||
|
|
||||||
class IPAddressField(forms.CharField):
|
|
||||||
def validate(self, value):
|
|
||||||
super().validate(value) # Run the default CharField validation
|
|
||||||
|
|
||||||
|
|
||||||
class DomainNameserverForm(forms.Form):
|
class DomainNameserverForm(forms.Form):
|
||||||
"""Form for changing nameservers."""
|
"""Form for changing nameservers."""
|
||||||
|
|
||||||
|
@ -35,7 +30,21 @@ class DomainNameserverForm(forms.Form):
|
||||||
|
|
||||||
server = forms.CharField(label="Name server", strip=True)
|
server = forms.CharField(label="Name server", strip=True)
|
||||||
|
|
||||||
ip = forms.CharField(label="IP Address (IPv4 or IPv6)", strip=True, required=False)
|
ip = forms.CharField(
|
||||||
|
label="IP address (IPv4 or IPv6)",
|
||||||
|
strip=True,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(DomainNameserverForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
# add custom error messages
|
||||||
|
self.fields["server"].error_messages.update(
|
||||||
|
{
|
||||||
|
"required": "A minimum of 2 name servers are required.",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
# clean is called from clean_forms, which is called from is_valid
|
# clean is called from clean_forms, which is called from is_valid
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
class="{% if label_classes %} {{ label_classes }}{% endif %}{% if label_tag == 'legend' %} {{ legend_classes }}{% endif %}"
|
class="{% if label_classes %} {{ label_classes }}{% endif %}{% if label_tag == 'legend' %} {{ legend_classes }}{% endif %}"
|
||||||
{% if not field.use_fieldset %}for="{{ widget.attrs.id }}"{% endif %}
|
{% if not field.use_fieldset %}for="{{ widget.attrs.id }}"{% endif %}
|
||||||
>
|
>
|
||||||
{{ field.label }}
|
{% if span_for_text %}
|
||||||
{% if widget.attrs.required %}
|
<span>{{ field.label }}</span>
|
||||||
<abbr class="usa-hint usa-hint--required" title="required">*</abbr>
|
{% else %}
|
||||||
{% endif %}
|
{{ field.label }}
|
||||||
|
{% endif %}
|
||||||
|
{% if widget.attrs.required %}
|
||||||
|
<abbr class="usa-hint usa-hint--required" title="required">*</abbr>
|
||||||
|
{% endif %}
|
||||||
</{{ label_tag }}>
|
</{{ label_tag }}>
|
||||||
|
|
|
@ -35,11 +35,14 @@
|
||||||
{{ form.domain }}
|
{{ form.domain }}
|
||||||
{% with sublabel_text="Example: ns"|concat:forloop.counter|concat:".example.com" %}
|
{% with sublabel_text="Example: ns"|concat:forloop.counter|concat:".example.com" %}
|
||||||
{% if forloop.counter <= 2 %}
|
{% if forloop.counter <= 2 %}
|
||||||
{% with attr_required=True add_group_class="usa-form-group--unstyled-error" %}
|
{# span_for_text will wrap the copy in s <span>, which we'll use in the JS for this component #}
|
||||||
|
{% with attr_required=True add_group_class="usa-form-group--unstyled-error" span_for_text=True %}
|
||||||
{% input_with_errors form.server %}
|
{% input_with_errors form.server %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% input_with_errors form.server %}
|
{% with span_for_text=True %}
|
||||||
|
{% input_with_errors form.server %}
|
||||||
|
{% endwith %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,14 +52,11 @@
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
<div class="tablet:grid-col-2">
|
<div class="tablet:grid-col-2">
|
||||||
{% comment %} TODO: remove this if for 1192 {% endcomment %}
|
<button type="button" class="usa-button usa-button--unstyled display-block delete-record margin-bottom-075">
|
||||||
{% if forloop.counter > 2 %}
|
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
||||||
<button type="button" class="usa-button usa-button--unstyled display-block delete-record margin-bottom-075">
|
<use xlink:href="{%static 'img/sprite.svg'%}#delete"></use>
|
||||||
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
</svg><span class="margin-left-05">Delete</span>
|
||||||
<use xlink:href="{%static 'img/sprite.svg'%}#delete"></use>
|
</button>
|
||||||
</svg><span class="margin-left-05">Delete</span>
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
type="submit"
|
type="submit"
|
||||||
class="usa-button usa-button--outline"
|
class="usa-button usa-button--outline"
|
||||||
name="btn-cancel-click"
|
name="btn-cancel-click"
|
||||||
aria-label="Reset the data in the Name Server form to the registry state (undo changes)"
|
aria-label="Reset the data in the name server form to the registry state (undo changes)"
|
||||||
>Cancel
|
>Cancel
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1464,7 +1464,12 @@ class TestDomainNameservers(TestDomainOverview):
|
||||||
# form submission was a post with an error, response should be a 200
|
# form submission was a post with an error, response should be a 200
|
||||||
# error text appears twice, once at the top of the page, once around
|
# error text appears twice, once at the top of the page, once around
|
||||||
# the required field. form requires a minimum of 2 name servers
|
# the required field. form requires a minimum of 2 name servers
|
||||||
self.assertContains(result, "This field is required.", count=2, status_code=200)
|
self.assertContains(
|
||||||
|
result,
|
||||||
|
"A minimum of 2 name servers are required.",
|
||||||
|
count=2,
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
def test_domain_nameservers_form_submit_subdomain_missing_ip(self):
|
def test_domain_nameservers_form_submit_subdomain_missing_ip(self):
|
||||||
"""Nameserver form catches missing ip error on subdomain.
|
"""Nameserver form catches missing ip error on subdomain.
|
||||||
|
@ -1632,7 +1637,12 @@ class TestDomainNameservers(TestDomainOverview):
|
||||||
# form submission was a post with an error, response should be a 200
|
# form submission was a post with an error, response should be a 200
|
||||||
# error text appears four times, twice at the top of the page,
|
# error text appears four times, twice at the top of the page,
|
||||||
# once around each required field.
|
# once around each required field.
|
||||||
self.assertContains(result, "This field is required", count=4, status_code=200)
|
self.assertContains(
|
||||||
|
result,
|
||||||
|
"A minimum of 2 name servers are required.",
|
||||||
|
count=4,
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestDomainAuthorizingOfficial(TestDomainOverview):
|
class TestDomainAuthorizingOfficial(TestDomainOverview):
|
||||||
|
@ -1800,7 +1810,11 @@ class TestDomainSecurityEmail(TestDomainOverview):
|
||||||
(
|
(
|
||||||
"RegistryError",
|
"RegistryError",
|
||||||
form_data_registry_error,
|
form_data_registry_error,
|
||||||
"Update failed. Cannot contact the registry.",
|
"""
|
||||||
|
We’re experiencing a system connection error. Please wait a few minutes
|
||||||
|
and try again. If you continue to receive this error after a few tries,
|
||||||
|
contact help@get.gov
|
||||||
|
""",
|
||||||
),
|
),
|
||||||
("ContactError", form_data_contact_error, "Value entered was wrong."),
|
("ContactError", form_data_contact_error, "Value entered was wrong."),
|
||||||
(
|
(
|
||||||
|
@ -1835,7 +1849,7 @@ class TestDomainSecurityEmail(TestDomainOverview):
|
||||||
self.assertEqual(len(messages), 1)
|
self.assertEqual(len(messages), 1)
|
||||||
message = messages[0]
|
message = messages[0]
|
||||||
self.assertEqual(message.tags, message_tag)
|
self.assertEqual(message.tags, message_tag)
|
||||||
self.assertEqual(message.message, expected_message)
|
self.assertEqual(message.message.strip(), expected_message.strip())
|
||||||
|
|
||||||
def test_domain_overview_blocked_for_ineligible_user(self):
|
def test_domain_overview_blocked_for_ineligible_user(self):
|
||||||
"""We could easily duplicate this test for all domain management
|
"""We could easily duplicate this test for all domain management
|
||||||
|
|
|
@ -39,9 +39,11 @@ class GenericError(Exception):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_error_mapping = {
|
_error_mapping = {
|
||||||
GenericErrorCodes.CANNOT_CONTACT_REGISTRY: (
|
GenericErrorCodes.CANNOT_CONTACT_REGISTRY: """
|
||||||
"Update failed. Cannot contact the registry."
|
We’re experiencing a system connection error. Please wait a few minutes
|
||||||
),
|
and try again. If you continue to receive this error after a few tries,
|
||||||
|
contact help@get.gov
|
||||||
|
""",
|
||||||
GenericErrorCodes.GENERIC_ERROR: ("Value entered was wrong."),
|
GenericErrorCodes.GENERIC_ERROR: ("Value entered was wrong."),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue