From 9059ce32815ff4e2b92ecd38c34caf661b179b44 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 15 Aug 2024 08:59:05 -0600 Subject: [PATCH] Suggestions + QOL changes --- src/registrar/admin.py | 10 +---- src/registrar/assets/js/get-gov-admin.js | 39 ++++++++++++++++++- src/registrar/models/senior_official.py | 4 -- .../admin/includes/contact_detail_list.html | 5 ++- .../admin/includes/detail_table_fieldset.html | 4 +- src/registrar/templatetags/custom_filters.py | 9 +++++ 6 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 736dd6f16..28e3af4d0 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -3060,15 +3060,7 @@ class PortfolioAdmin(ListHeaderAdmin): def change_view(self, request, object_id, form_url="", extra_context=None): """Add related suborganizations and domain groups""" - obj = self.get_object(request, object_id) - - # ---- Domain Groups - domain_groups = DomainGroup.objects.filter(portfolio=obj) - - # ---- Suborganizations - suborganizations = Suborganization.objects.filter(portfolio=obj) - - extra_context = {"domain_groups": domain_groups, "suborganizations": suborganizations} + extra_context = {"skip_additional_contact_info": True} return super().change_view(request, object_id, form_url, extra_context) def save_model(self, request, obj, form, change): diff --git a/src/registrar/assets/js/get-gov-admin.js b/src/registrar/assets/js/get-gov-admin.js index f376af40b..b6ba82821 100644 --- a/src/registrar/assets/js/get-gov-admin.js +++ b/src/registrar/assets/js/get-gov-admin.js @@ -765,13 +765,18 @@ function initializeWidgetOnList(list, parentId) { */ (function dynamicPortfolioFields(){ + // the federal agency change listener fires on page load, which we don't want. + var isInitialPageLoad = true + + // This is the additional information that exists beneath the SO element. + var contactList = document.querySelector(".field-senior_official .dja-address-contact-list"); document.addEventListener('DOMContentLoaded', function() { - + let isPortfolioPage = document.getElementById("portfolio_form"); if (!isPortfolioPage) { return; } - + // $ symbolically denotes that this is using jQuery let $federalAgency = django.jQuery("#id_federal_agency"); let organizationType = document.getElementById("id_organization_type"); @@ -797,6 +802,12 @@ function initializeWidgetOnList(list, parentId) { }); function handleFederalAgencyChange(federalAgency, organizationType) { + // Don't do anything on page load + if (isInitialPageLoad) { + isInitialPageLoad = false; + return; + } + // Set the org type to federal if an agency is selected let selectedText = federalAgency.find("option:selected").text(); @@ -822,6 +833,10 @@ function initializeWidgetOnList(list, parentId) { return; } + // Hide the contactList initially. + // If we can update the contact information, it'll be shown again. + hideElement(contactList.parentElement); + let seniorOfficialApi = document.getElementById("senior_official_from_agency_json_url").value; fetch(`${seniorOfficialApi}?agency_name=${selectedText}`) .then(response => { @@ -840,6 +855,10 @@ function initializeWidgetOnList(list, parentId) { return; } + // Update the "contact details" blurb beneath senior official + updateContactInfo(data); + showElement(contactList.parentElement); + let seniorOfficialId = data.id; let seniorOfficialName = [data.first_name, data.last_name].join(" "); if (!seniorOfficialId || !seniorOfficialName || !seniorOfficialName.trim()){ @@ -862,6 +881,22 @@ function initializeWidgetOnList(list, parentId) { .catch(error => console.error("Error fetching senior official: ", error)); } + function updateContactInfo(data) { + if (!contactList) return; + + const titleSpan = contactList.querySelector("#contact_info_title"); + const emailSpan = contactList.querySelector("#contact_info_email"); + const phoneSpan = contactList.querySelector("#contact_info_phone"); + + if (titleSpan) titleSpan.textContent = data.title || ""; + if (emailSpan) { + emailSpan.textContent = data.email || ""; + const clipboardInput = contactList.querySelector(".admin-icon-group input"); + if (clipboardInput) clipboardInput.value = data.email || ""; + } + if (phoneSpan) phoneSpan.textContent = data.phone || ""; + } + function handleStateTerritoryChange(stateTerritory, urbanizationField) { let selectedValue = stateTerritory.value; if (selectedValue === "PR") { diff --git a/src/registrar/models/senior_official.py b/src/registrar/models/senior_official.py index 7ae96238b..38ce4f35d 100644 --- a/src/registrar/models/senior_official.py +++ b/src/registrar/models/senior_official.py @@ -54,10 +54,6 @@ class SeniorOfficial(TimeStampedModel): names = [n for n in [self.first_name, self.last_name] if n] return " ".join(names) if names else "Unknown" - def has_contact_info(self): - """Determines if this user has contact information, such as an email or phone number.""" - return bool(self.title or self.email or self.phone) - def __str__(self): if self.first_name or self.last_name: return self.get_formatted_name() diff --git a/src/registrar/templates/django/admin/includes/contact_detail_list.html b/src/registrar/templates/django/admin/includes/contact_detail_list.html index 397e2e1a0..054836fd3 100644 --- a/src/registrar/templates/django/admin/includes/contact_detail_list.html +++ b/src/registrar/templates/django/admin/includes/contact_detail_list.html @@ -1,4 +1,5 @@ {% load i18n static %} +{% load custom_filters %}
@@ -12,7 +13,7 @@
{% endif %} - {% if user.has_contact_info %} + {% if user|has_contact_info %} {# Title #} {% if user.title %} {{ user.title }} @@ -42,7 +43,7 @@ No additional contact information found.
{% endif %} - {% if user_verification_type %} + {% if user_verification_type and not skip_additional_contact_info %} {{ user_verification_type }} {% endif %}
diff --git a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html index 067b69c07..683f33117 100644 --- a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html +++ b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html @@ -184,7 +184,9 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html) {% include "django/admin/includes/contact_detail_list.html" with user=original_object.creator no_title_top_padding=field.is_readonly user_verification_type=original_object.creator.get_verification_type_display%} - {% include "django/admin/includes/user_detail_list.html" with user=original_object.creator no_title_top_padding=field.is_readonly %} + {% if not skip_additional_contact_info %} + {% include "django/admin/includes/user_detail_list.html" with user=original_object.creator no_title_top_padding=field.is_readonly %} + {% endif%} {% elif field.field.name == "submitter" %}
diff --git a/src/registrar/templatetags/custom_filters.py b/src/registrar/templatetags/custom_filters.py index e90b3b17f..1619f9b15 100644 --- a/src/registrar/templatetags/custom_filters.py +++ b/src/registrar/templatetags/custom_filters.py @@ -159,3 +159,12 @@ def and_filter(value, arg): Usage: {{ value|and:arg }} """ return bool(value and arg) + +@register.filter(name="has_contact_info") +def has_contact_info(user): + """Checks if the given object has the attributes: title, email, phone + and checks if at least one of those is not null.""" + if not hasattr(user, "title") or not hasattr(user, "email") or not hasattr(user, "phone"): + return False + else: + return bool(user.title or user.email or user.phone) \ No newline at end of file