mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-15 22:14:15 +02:00
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:
commit
5236370e63
9 changed files with 176 additions and 39 deletions
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
|
52
src/registrar/templates/admin/stacked.html
Normal file
52
src/registrar/templates/admin/stacked.html
Normal 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>
|
|
@ -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 %}
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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 %}
|
|
@ -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 %}
|
||||||
|
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue