Merge pull request #2005 from cisagov/za/1947-contact-info-domain-information-inline

(on getgov-za) Ticket #1947: Contact info on the domain information inline
This commit is contained in:
zandercymatics 2024-04-18 10:46:39 -06:00 committed by GitHub
commit 5236370e63
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 176 additions and 39 deletions

View file

@ -1509,10 +1509,11 @@ class DomainInformationInline(admin.StackedInline):
We had issues inheriting from both StackedInline We had issues inheriting from both StackedInline
and the source DomainInformationAdmin since these and the source DomainInformationAdmin since these
classes conflict, so we'll just pull what we need classes conflict, so we'll just pull what we need
from DomainInformationAdmin""" from DomainInformationAdmin
"""
form = DomainInformationInlineForm form = DomainInformationInlineForm
template = "django/admin/includes/domain_info_inline_stacked.html"
model = models.DomainInformation model = models.DomainInformation
fieldsets = copy.deepcopy(DomainInformationAdmin.fieldsets) fieldsets = copy.deepcopy(DomainInformationAdmin.fieldsets)
@ -1522,10 +1523,8 @@ class DomainInformationInline(admin.StackedInline):
del fieldsets[index] del fieldsets[index]
break break
readonly_fields = DomainInformationAdmin.readonly_fields
analyst_readonly_fields = DomainInformationAdmin.analyst_readonly_fields analyst_readonly_fields = DomainInformationAdmin.analyst_readonly_fields
# For each filter_horizontal, init in admin js extendFilterHorizontalWidgets
# to activate the edit/delete/view buttons
filter_horizontal = ("other_contacts",)
autocomplete_fields = [ autocomplete_fields = [
"creator", "creator",
@ -1691,11 +1690,15 @@ class DomainAdmin(ListHeaderAdmin):
if extra_context is None: if extra_context is None:
extra_context = {} extra_context = {}
# Pass in what the an extended expiration date would be for the expiration date modal
if object_id is not None: if object_id is not None:
domain = Domain.objects.get(pk=object_id) domain = Domain.objects.get(pk=object_id)
years_to_extend_by = self._get_calculated_years_for_exp_date(domain)
# Used in the custom contact view
if domain is not None and hasattr(domain, "domain_info"):
extra_context["original_object"] = domain.domain_info
# 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: try:
curr_exp_date = domain.registry_expiration_date curr_exp_date = domain.registry_expiration_date
except KeyError: except KeyError:

View file

@ -596,6 +596,7 @@ address.dja-address-contact-list {
right: auto; right: auto;
left: 4px; left: 4px;
height: 100%; height: 100%;
top: -1px;
} }
button { button {
font-size: unset !important; font-size: unset !important;

View file

@ -0,0 +1,52 @@
{% load i18n admin_urls %}
{% load i18n static %}
{% comment %}
This is copied from Djangos implementation of this template, with added "blocks"
It is not inherently customizable on its own, so we can modify this instead.
https://github.com/django/django/blob/main/django/contrib/admin/templates/admin/edit_inline/stacked.html
{% endcomment %}
<div class="js-inline-admin-formset inline-group"
id="{{ inline_admin_formset.formset.prefix }}-group"
data-inline-type="stacked"
data-inline-formset="{{ inline_admin_formset.inline_formset_data }}">
<fieldset class="module {{ inline_admin_formset.classes }}">
{% if inline_admin_formset.formset.max_num == 1 %}
<h2>{{ inline_admin_formset.opts.verbose_name|capfirst }}</h2>
{% else %}
<h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
{% endif %}
{{ inline_admin_formset.formset.management_form }}
{{ inline_admin_formset.formset.non_form_errors }}
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if inline_admin_form.original or inline_admin_form.show_url %} has_original{% endif %}{% if forloop.last and inline_admin_formset.has_add_permission %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if forloop.last and inline_admin_formset.has_add_permission %}empty{% else %}{{ forloop.counter0 }}{% endif %}">
<h3><b>{{ inline_admin_formset.opts.verbose_name|capfirst }}:</b> <span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} <a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="{{ inline_admin_formset.has_change_permission|yesno:'inlinechangelink,inlineviewlink' }}">{% if inline_admin_formset.has_change_permission %}{% translate "Change" %}{% else %}{% translate "View" %}{% endif %}</a>{% endif %}
{% else %}#{{ forloop.counter }}{% endif %}</span>
{% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% translate "View on site" %}</a>{% endif %}
{% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %}
</h3>
{% if inline_admin_form.form.non_field_errors %}
{{ inline_admin_form.form.non_field_errors }}
{% endif %}
{% for fieldset in inline_admin_form %}
{# .gov override #}
{% block fieldset %}
{% include "admin/includes/fieldset.html" %}
{% endblock fieldset%}
{# End of .gov override #}
{% endfor %}
{% if inline_admin_form.needs_explicit_pk_field %}
{{ inline_admin_form.pk_field.field }}
{% endif %}
{% if inline_admin_form.fk_field %}
{{ inline_admin_form.fk_field.field }}
{% endif %}
</div>
{% endfor %}
</fieldset>
</div>

View file

@ -9,7 +9,9 @@
{% include "django/admin/includes/domain_information_fieldset.html" %} {% include "django/admin/includes/domain_information_fieldset.html" %}
Use detail_table_fieldset as an example, or just extend it. Use detail_table_fieldset as an example, or just extend it.
original_object is just a variable name for "DomainInformation" or "DomainRequest"
{% endcomment %} {% endcomment %}
{% include "django/admin/includes/detail_table_fieldset.html" %} {% include "django/admin/includes/detail_table_fieldset.html" with original_object=original %}
{% endfor %} {% endfor %}
{% endblock %} {% endblock %}

View file

@ -13,8 +13,10 @@
{% include "django/admin/includes/domain_information_fieldset.html" %} {% include "django/admin/includes/domain_information_fieldset.html" %}
Use detail_table_fieldset as an example, or just extend it. Use detail_table_fieldset as an example, or just extend it.
original_object is just a variable name for "DomainInformation" or "DomainRequest"
{% endcomment %} {% endcomment %}
{% include "django/admin/includes/detail_table_fieldset.html" %} {% include "django/admin/includes/detail_table_fieldset.html" with original_object=original %}
{% endfor %} {% endfor %}
{% endblock %} {% endblock %}

View file

@ -5,7 +5,7 @@
This is using a custom implementation fieldset.html (see admin/fieldset.html) This is using a custom implementation fieldset.html (see admin/fieldset.html)
{% endcomment %} {% endcomment %}
{% block field_readonly %} {% block field_readonly %}
{% with all_contacts=original.other_contacts.all %} {% with all_contacts=original_object.other_contacts.all %}
{% if field.field.name == "other_contacts" %} {% if field.field.name == "other_contacts" %}
{% if all_contacts.count > 2 %} {% if all_contacts.count > 2 %}
<div class="readonly"> <div class="readonly">
@ -54,7 +54,7 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html)
{% elif field.field.name == "alternative_domains" %} {% elif field.field.name == "alternative_domains" %}
<div class="readonly"> <div class="readonly">
{% with current_path=request.get_full_path %} {% with current_path=request.get_full_path %}
{% for alt_domain in original.alternative_domains.all %} {% for alt_domain in original_object.alternative_domains.all %}
<a href="{% url 'admin:registrar_website_change' alt_domain.id %}?{{ 'return_path='|add:current_path }}">{{ alt_domain }}</a>{% if not forloop.last %}, {% endif %} <a href="{% url 'admin:registrar_website_change' alt_domain.id %}?{{ 'return_path='|add:current_path }}">{{ alt_domain }}</a>{% if not forloop.last %}, {% endif %}
{% endfor %} {% endfor %}
{% endwith %} {% endwith %}
@ -69,24 +69,21 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html)
{% if field.field.name == "creator" %} {% if field.field.name == "creator" %}
<div class="flex-container"> <div class="flex-container">
<label aria-label="Creator contact details"></label> <label aria-label="Creator contact details"></label>
{% include "django/admin/includes/contact_detail_list.html" with user=original.creator no_title_top_padding=field.is_readonly %} {% include "django/admin/includes/contact_detail_list.html" with user=original_object.creator no_title_top_padding=field.is_readonly %}
</div>
<div class="flex-container">
<label aria-label="User summary details"></label>
{% include "django/admin/includes/user_detail_list.html" with user=original.creator no_title_top_padding=field.is_readonly %}
</div> </div>
{% include "django/admin/includes/user_detail_list.html" with user=original_object.creator no_title_top_padding=field.is_readonly %}
{% elif field.field.name == "submitter" %} {% elif field.field.name == "submitter" %}
<div class="flex-container"> <div class="flex-container">
<label aria-label="Submitter contact details"></label> <label aria-label="Submitter contact details"></label>
{% include "django/admin/includes/contact_detail_list.html" with user=original.submitter no_title_top_padding=field.is_readonly %} {% include "django/admin/includes/contact_detail_list.html" with user=original_object.submitter no_title_top_padding=field.is_readonly %}
</div> </div>
{% elif field.field.name == "authorizing_official" %} {% elif field.field.name == "authorizing_official" %}
<div class="flex-container"> <div class="flex-container">
<label aria-label="Authorizing official contact details"></label> <label aria-label="Authorizing official contact details"></label>
{% include "django/admin/includes/contact_detail_list.html" with user=original.authorizing_official no_title_top_padding=field.is_readonly %} {% include "django/admin/includes/contact_detail_list.html" with user=original_object.authorizing_official no_title_top_padding=field.is_readonly %}
</div> </div>
{% elif field.field.name == "other_contacts" and original.other_contacts.all %} {% elif field.field.name == "other_contacts" and original_object.other_contacts.all %}
{% with all_contacts=original.other_contacts.all %} {% with all_contacts=original_object.other_contacts.all %}
{% if all_contacts.count > 2 %} {% if all_contacts.count > 2 %}
<details class="margin-top-1 dja-detail-table" aria-role="button" open> <details class="margin-top-1 dja-detail-table" aria-role="button" open>
<summary class="padding-1 padding-left-0 dja-details-summary">Details</summary> <summary class="padding-1 padding-left-0 dja-details-summary">Details</summary>
@ -104,7 +101,6 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html)
<td class="padding-left-1">{{ contact.title }}</td> <td class="padding-left-1">{{ contact.title }}</td>
<td class="padding-left-1"> <td class="padding-left-1">
{{ contact.email }} {{ contact.email }}
</td> </td>
<td class="padding-left-1">{{ contact.phone }}</td> <td class="padding-left-1">{{ contact.phone }}</td>
<td class="padding-left-1 text-size-small"> <td class="padding-left-1 text-size-small">

View file

@ -0,0 +1,6 @@
{% extends 'admin/stacked.html' %}
{% load i18n static %}
{% block fieldset %}
{% include "django/admin/includes/detail_table_fieldset.html" with original_object=original_object %}
{% endblock %}

View file

@ -5,24 +5,27 @@
{% with rejected_requests_count=user.get_rejected_requests_count %} {% with rejected_requests_count=user.get_rejected_requests_count %}
{% with ineligible_requests_count=user.get_ineligible_requests_count %} {% with ineligible_requests_count=user.get_ineligible_requests_count %}
{% if approved_domains_count|add:active_requests_count|add:rejected_requests_count|add:ineligible_requests_count > 0 %} {% if approved_domains_count|add:active_requests_count|add:rejected_requests_count|add:ineligible_requests_count > 0 %}
<ul class="dja-status-list"> <div class="flex-container">
{% if approved_domains_count > 0 %} <label aria-label="User summary details"></label>
{# Approved domains #} <ul class="dja-status-list">
<li>Approved domains: {{ approved_domains_count }}</li> {% if approved_domains_count > 0 %}
{% endif %} {# Approved domains #}
{% if active_requests_count > 0 %} <li>Approved domains: {{ approved_domains_count }}</li>
{# Active requests #} {% endif %}
<li>Active requests: {{ active_requests_count }}</li> {% if active_requests_count > 0 %}
{% endif %} {# Active requests #}
{% if rejected_requests_count > 0 %} <li>Active requests: {{ active_requests_count }}</li>
{# Rejected requests #} {% endif %}
<li>Rejected requests: {{ rejected_requests_count }}</li> {% if rejected_requests_count > 0 %}
{% endif %} {# Rejected requests #}
{% if ineligible_requests_count > 0 %} <li>Rejected requests: {{ rejected_requests_count }}</li>
{# Ineligible requests #} {% endif %}
<li>Ineligible requests: {{ ineligible_requests_count }}</li> {% if ineligible_requests_count > 0 %}
{% endif %} {# Ineligible requests #}
</ul> <li>Ineligible requests: {{ ineligible_requests_count }}</li>
{% endif %}
</ul>
</div>
{% endif %} {% endif %}
{% endwith %} {% endwith %}
{% endwith %} {% endwith %}

View file

@ -85,6 +85,78 @@ class TestDomainAdmin(MockEppLib, WebTest):
) )
super().setUp() super().setUp()
@less_console_noise_decorator
def test_contact_fields_on_domain_change_form_have_detail_table(self):
"""Tests if the contact fields in the inlined Domain information have the detail table
which displays title, email, and phone"""
# Create fake creator
_creator = User.objects.create(
username="MrMeoward",
first_name="Meoward",
last_name="Jones",
)
# Due to the relation between User <==> Contact,
# the underlying contact has to be modified this way.
_creator.contact.email = "meoward.jones@igorville.gov"
_creator.contact.phone = "(555) 123 12345"
_creator.contact.title = "Treat inspector"
_creator.contact.save()
# Create a fake domain request
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
domain_request.approve()
_domain_info = DomainInformation.objects.filter(domain=domain_request.approved_domain).get()
domain = Domain.objects.filter(domain_info=_domain_info).get()
p = "adminpass"
self.client.login(username="superuser", password=p)
response = self.client.get(
"/admin/registrar/domain/{}/change/".format(domain.pk),
follow=True,
)
# Make sure the page loaded, and that we're on the right page
self.assertEqual(response.status_code, 200)
self.assertContains(response, domain.name)
# Check that the fields have the right values.
# == Check for the creator == #
# Check for the right title, email, and phone number in the response.
# We only need to check for the end tag
# (Otherwise this test will fail if we change classes, etc)
self.assertContains(response, "Treat inspector")
self.assertContains(response, "meoward.jones@igorville.gov")
self.assertContains(response, "(555) 123 12345")
# Check for the field itself
self.assertContains(response, "Meoward Jones")
# == Check for the submitter == #
self.assertContains(response, "mayor@igorville.gov")
self.assertContains(response, "Admin Tester")
self.assertContains(response, "(555) 555 5556")
self.assertContains(response, "Testy2 Tester2")
# == Check for the authorizing_official == #
self.assertContains(response, "testy@town.com")
self.assertContains(response, "Chief Tester")
self.assertContains(response, "(555) 555 5555")
# Includes things like readonly fields
self.assertContains(response, "Testy Tester")
# == Test the other_employees field == #
self.assertContains(response, "testy2@town.com")
self.assertContains(response, "Another Tester")
self.assertContains(response, "(555) 555 5557")
# Test for the copy link
self.assertContains(response, "usa-button__clipboard")
@patch("registrar.admin.DomainAdmin._get_current_date", return_value=date(2024, 1, 1)) @patch("registrar.admin.DomainAdmin._get_current_date", return_value=date(2024, 1, 1))
def test_extend_expiration_date_button(self, mock_date_today): def test_extend_expiration_date_button(self, mock_date_today):
""" """