From 4f77fa661f9ca24b5c41aecf09ec56e35a0ff1bb Mon Sep 17 00:00:00 2001 From: Kim Allen Date: Fri, 6 Jun 2025 11:28:45 -0700 Subject: [PATCH] #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 --- .../templates/includes/senior_official.html | 6 +- .../portfolio_organization_info.html | 98 ++++++++++--------- src/registrar/tests/test_views_portfolio.py | 38 +++++-- src/registrar/views/portfolios.py | 1 + 4 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/registrar/templates/includes/senior_official.html b/src/registrar/templates/includes/senior_official.html index 52b4ab6eb..04ee1afec 100644 --- a/src/registrar/templates/includes/senior_official.html +++ b/src/registrar/templates/includes/senior_official.html @@ -39,15 +39,15 @@

{% if form.full_name.value is not None %} - {% include "includes/input_read_only.html" with field=form.full_name %} +

{{ form.full_name.value }}

{% endif %} {% if form.title.value is not None %} - {% include "includes/input_read_only.html" with field=form.title %} +

{{ form.title.value }}

{% endif %} {% if form.email.value is not None %} - {% include "includes/input_read_only.html" with field=form.email %} +

{{ form.email.value }}

{% endif %}
{% endif %} diff --git a/src/registrar/templates/portfolio_organization_info.html b/src/registrar/templates/portfolio_organization_info.html index 546b06b83..e27a85cc4 100644 --- a/src/registrar/templates/portfolio_organization_info.html +++ b/src/registrar/templates/portfolio_organization_info.html @@ -21,16 +21,17 @@ {% block breadcrumb %} {% endblock breadcrumb %} + {% include "includes/form_errors.html" with form=form %} {% block messages %} @@ -42,49 +43,50 @@

The name of your organization will be publicly listed as the domain registrant.

{% if has_edit_portfolio_permission %} -

- Your organization name can’t be updated here. - To suggest an update, email help@get.gov. -

- - {% include "includes/required_fields.html" %} -
- {% csrf_token %} -

Organization name

-

- {{ portfolio.federal_agency }} -

- {% 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 %} - -
- {% else %} -

Organization name

+

+ Your organization name can’t be updated here. + To suggest an update, email help@get.gov. +

+ {% endif %} +

Organization admins

+ + +

Organization name and address

+ + {% if has_edit_portfolio_permission %} + {% include "includes/required_fields.html" with remove_margin_top=True %} +
+ {% csrf_token %} +

Organization name

+ {% if portfolio.organization_name %} + {{ portfolio.organization_name }} + {% else %} {{ portfolio.federal_agency }} + {% endif %}

- {% 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 %} + +
+ {% else %} +
+ {% include "includes/organization_address.html" with organization=portfolio %} +
{% endif %} diff --git a/src/registrar/tests/test_views_portfolio.py b/src/registrar/tests/test_views_portfolio.py index 83a3e9516..08e14bdfd 100644 --- a/src/registrar/tests/test_views_portfolio.py +++ b/src/registrar/tests/test_views_portfolio.py @@ -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, '

Organization name

') - # The read only label for city will be a h4 - self.assertNotContains(response, '

City

') - self.assertNotContains(response, '

Los Angeles

') + self.assertContains(response, "

Organization admins

") + self.assertContains(response, "

Organization name and address

") + self.assertContains( + response, '

Organization name

' + ) + self.assertNotContains(response, "
") 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, '

Organization name

' + ) + self.assertContains(org_info_response, "
") + @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): diff --git a/src/registrar/views/portfolios.py b/src/registrar/views/portfolios.py index 008f60e51..4d481fbeb 100644 --- a/src/registrar/views/portfolios.py +++ b/src/registrar/views/portfolios.py @@ -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):