#3741: Show a list of org admins on the org details page [KMA] (#3845)

* Add admin list on org info page with rough styling

* Use an unstyled unordered list for admin list

* Remove admin title

* Update indenting and change h4 to h3 to not jump heading levels

* Readd accidentally deleted line; add another heading to give it semantic sense

* Update with new design for headings and field data

* Update tests to reflect html changes

* Fix formating issue

* Update styling; update field used for org name

* Update org name value to show fed agency if org name doesn't exist

* Utilize address template

* Update styling to be determined by top-level wrapper

* Linter updates

* Update test to check address

* Use federal_agency as intended
This commit is contained in:
Kim Allen 2025-06-06 11:28:45 -07:00 committed by GitHub
parent 651112cca5
commit 4f77fa661f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 84 additions and 59 deletions

View file

@ -39,15 +39,15 @@
</p>
<div class="desktop:margin-top-4">
{% if form.full_name.value is not None %}
{% include "includes/input_read_only.html" with field=form.full_name %}
<p class="margin-top-0 margin-bottom-0">{{ form.full_name.value }}</p>
{% endif %}
{% if form.title.value is not None %}
{% include "includes/input_read_only.html" with field=form.title %}
<p class="margin-top-0 margin-bottom-0">{{ form.title.value }}</p>
{% endif %}
{% if form.email.value is not None %}
{% include "includes/input_read_only.html" with field=form.email %}
<p class="margin-top-0 margin-bottom-0">{{ form.email.value }}</p>
{% endif %}
</div>
{% endif %}

View file

@ -21,16 +21,17 @@
{% block breadcrumb %}
<!-- Navigation breadcrumbs -->
<nav class="usa-breadcrumb padding-top-0" aria-label="Portfolio organization breadcrumb">
<ol class="usa-breadcrumb__list">
<li class="usa-breadcrumb__list-item">
<a href="{% url 'organization' %}" class="usa-breadcrumb__link"><span>{{ portfolio }}</span></a>
</li>
<li class="usa-breadcrumb__list-item usa-current" aria-current="page">
<span>Organization</span>
</li>
</ol>
<ol class="usa-breadcrumb__list">
<li class="usa-breadcrumb__list-item">
<a href="{% url 'organization' %}" class="usa-breadcrumb__link"><span>{{ portfolio }}</span></a>
</li>
<li class="usa-breadcrumb__list-item usa-current" aria-current="page">
<span>Organization</span>
</li>
</ol>
</nav>
{% endblock breadcrumb %}
<!-- Form messages -->
{% include "includes/form_errors.html" with form=form %}
{% block messages %}
@ -42,49 +43,50 @@
<p>The name of your organization will be publicly listed as the domain registrant.</p>
{% if has_edit_portfolio_permission %}
<p>
Your organization name cant be updated here.
To suggest an update, email <a href="mailto:help@get.gov" class="usa-link">help@get.gov</a>.
</p>
{% include "includes/required_fields.html" %}
<form class="usa-form usa-form--large desktop:margin-top-4" method="post" novalidate>
{% csrf_token %}
<h4 class="margin-bottom-05">Organization name</h4>
<p class="margin-top-0">
{{ portfolio.federal_agency }}
</p>
{% input_with_errors form.address_line1 %}
{% input_with_errors form.address_line2 %}
{% input_with_errors form.city %}
{% input_with_errors form.state_territory %}
{% with add_class="usa-input--small" sublabel_text="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789." %}
{% input_with_errors form.zipcode %}
{% endwith %}
<button type="submit" class="usa-button">
Save
</button>
</form>
{% else %}
<h4 class="margin-bottom-05">Organization name</h4>
<p>
Your organization name cant be updated here.
To suggest an update, email <a href="mailto:help@get.gov" class="usa-link">help@get.gov</a>.
</p>
{% endif %}
<h2>Organization admins</h2>
<ul class="usa-list usa-list--unstyled margin-top-2 margin-bottom-0">
{% for admin in portfolio_admins %}
<li>
<p class="margin-bottom-0">{{admin.first_name}} {{admin.last_name}}</p>
<p class="margin-top-0">{{admin.email}}</p>
</li>
{% endfor %}
</ul>
<h2>Organization name and address</h2>
{% if has_edit_portfolio_permission %}
{% include "includes/required_fields.html" with remove_margin_top=True %}
<form class="usa-form usa-form--large" method="post" novalidate>
{% csrf_token %}
<p class="margin-bottom-05 text-primary-darker text-bold">Organization name</p>
<p class="margin-top-0">
{% if portfolio.organization_name %}
{{ portfolio.organization_name }}
{% else %}
{{ portfolio.federal_agency }}
{% endif %}
</p>
{% if form.address_line1.value is not None %}
{% include "includes/input_read_only.html" with field=form.address_line1 %}
{% endif %}
{% if form.address_line2.value is not None %}
{% include "includes/input_read_only.html" with field=form.address_line2 %}
{% endif %}
{% if form.city.value is not None %}
{% include "includes/input_read_only.html" with field=form.city %}
{% endif %}
{% if form.state_territory.value is not None %}
{% include "includes/input_read_only.html" with field=form.state_territory %}
{% endif %}
{% if form.zipcode.value is not None %}
{% include "includes/input_read_only.html" with field=form.zipcode %}
{% endif %}
{% input_with_errors form.address_line1 %}
{% input_with_errors form.address_line2 %}
{% input_with_errors form.city %}
{% input_with_errors form.state_territory %}
{% with add_class="usa-input--small" sublabel_text="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789." %}
{% input_with_errors form.zipcode %}
{% endwith %}
<button type="submit" class="usa-button">
Save
</button>
</form>
{% else %}
<div class="margin-top-2">
{% include "includes/organization_address.html" with organization=portfolio %}
</div>
{% endif %}
</div>
</div>

View file

@ -309,7 +309,7 @@ class TestPortfolio(WebTest):
@less_console_noise_decorator
def test_portfolio_organization_info_page_edit_access(self):
"""Test that user with a portfolio can access the portfolio organization page, read only"""
"""Test that user with a portfolio can access the portfolio organization page, edit access"""
self.app.set_user(self.user.username)
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
user=self.user,
@ -327,13 +327,36 @@ class TestPortfolio(WebTest):
response = self.app.get(reverse("organization-info"))
# Assert the response is a 200
self.assertEqual(response.status_code, 200)
# The label for Federal agency will always be a h4
self.assertContains(response, '<h4 class="margin-bottom-05">Organization name</h4>')
# The read only label for city will be a h4
self.assertNotContains(response, '<h4 class="margin-bottom-05">City</h4>')
self.assertNotContains(response, '<p class="margin-top-0">Los Angeles</p>')
self.assertContains(response, "<h2>Organization admins</h2>")
self.assertContains(response, "<h2>Organization name and address</h2>")
self.assertContains(
response, '<p class="margin-bottom-05 text-primary-darker text-bold">Organization name</p>'
)
self.assertNotContains(response, "<address>")
self.assertContains(response, 'for="id_city"')
@less_console_noise_decorator
def test_portfolio_organization_detail_pages_shows_read_only(self):
"""Test that breadcrumb menus display on portfolio detail pages"""
self.app.set_user(self.user.username)
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
user=self.user,
portfolio=self.portfolio,
additional_permissions=[
UserPortfolioPermissionChoices.VIEW_PORTFOLIO,
],
)
self.portfolio.organization_name = "Hotel California"
self.portfolio.save()
with override_flag("organization_feature", active=True):
org_info_response = self.app.get(reverse("organization-info"))
# We don't use the label "Organization name" in the view-only view
self.assertNotContains(
org_info_response, '<p class="margin-bottom-05 text-primary-darker text-bold">Organization name</p>'
)
self.assertContains(org_info_response, "<address>")
@less_console_noise_decorator
def test_portfolio_organization_detail_pages_include_breadcrumb(self):
"""Test that breadcrumb menus display on portfolio detail pages"""
@ -491,8 +514,7 @@ class TestPortfolio(WebTest):
self.portfolio.save()
page = self.app.get(reverse("organization-info"))
# Org name in Sidenav, main nav, webpage title, and breadcrumb
self.assertContains(page, "Hotel California", count=4)
self.assertContains(page, "Non-Federal Agency")
self.assertContains(page, "Hotel California", count=5)
@less_console_noise_decorator
def test_org_form_invalid_update(self):

View file

@ -935,6 +935,7 @@ class PortfolioOrganizationInfoView(DetailView, FormMixin):
context = super().get_context_data(**kwargs)
portfolio = self.request.session.get("portfolio")
context["has_edit_portfolio_permission"] = self.request.user.has_edit_portfolio_permission(portfolio)
context["portfolio_admins"] = portfolio.portfolio_admin_users
return context
def get_object(self, queryset=None):