diff --git a/src/registrar/admin.py b/src/registrar/admin.py
index 4b05bbb6d..8bdebc9fb 100644
--- a/src/registrar/admin.py
+++ b/src/registrar/admin.py
@@ -163,6 +163,18 @@ class MyUserAdminForm(UserChangeForm):
"user_permissions": NoAutocompleteFilteredSelectMultiple("user_permissions", False),
}
+ # Loads "tabtitle" for this admin page so that on render the
+ # element will only have the model name instead of
+ # the default string loaded by native Django admin code.
+ # (Eg. instead of "Select contact to change", display "Contacts")
+ # see "base_site.html" for the code.
+ def changelist_view(self, request, extra_context=None):
+ if extra_context is None:
+ extra_context = {}
+ extra_context["tabtitle"] = str(self.opts.verbose_name_plural).title()
+ # Get the filtered values
+ return super().changelist_view(request, extra_context=extra_context)
+
def __init__(self, *args, **kwargs):
"""Custom init to modify the user form"""
super(MyUserAdminForm, self).__init__(*args, **kwargs)
@@ -523,6 +535,18 @@ class CustomLogEntryAdmin(LogEntryAdmin):
"user_url",
]
+ # Loads "tabtitle" for this admin page so that on render the
+ # element will only have the model name instead of
+ # the default string loaded by native Django admin code.
+ # (Eg. instead of "Select contact to change", display "Contacts")
+ # see "base_site.html" for the code.
+ def changelist_view(self, request, extra_context=None):
+ if extra_context is None:
+ extra_context = {}
+ extra_context["tabtitle"] = str(self.opts.verbose_name_plural).title()
+ # Get the filtered values
+ return super().changelist_view(request, extra_context=extra_context)
+
# We name the custom prop 'resource' because linter
# is not allowing a short_description attr on it
# This gets around the linter limitation, for now.
@@ -542,13 +566,6 @@ class CustomLogEntryAdmin(LogEntryAdmin):
change_form_template = "admin/change_form_no_submit.html"
add_form_template = "admin/change_form_no_submit.html"
- # Select log entry to change -> Log entries
- def changelist_view(self, request, extra_context=None):
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "Log entries"
- return super().changelist_view(request, extra_context=extra_context)
-
# #786: Skipping on updating audit log tab titles for now
# def change_view(self, request, object_id, form_url="", extra_context=None):
# if extra_context is None:
@@ -629,6 +646,18 @@ class AdminSortFields:
class AuditedAdmin(admin.ModelAdmin):
"""Custom admin to make auditing easier."""
+ # Loads "tabtitle" for this admin page so that on render the
+ # element will only have the model name instead of
+ # the default string loaded by native Django admin code.
+ # (Eg. instead of "Select contact to change", display "Contacts")
+ # see "base_site.html" for the code.
+ def changelist_view(self, request, extra_context=None):
+ if extra_context is None:
+ extra_context = {}
+ extra_context["tabtitle"] = str(self.opts.verbose_name_plural).title()
+ # Get the filtered values
+ return super().changelist_view(request, extra_context=extra_context)
+
def history_view(self, request, object_id, extra_context=None):
"""On clicking 'History', take admin to the auditlog view for an object."""
return HttpResponseRedirect(
@@ -1029,6 +1058,18 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
extra_context = {"domain_requests": domain_requests, "domains": domains, "portfolios": portfolios}
return super().change_view(request, object_id, form_url, extra_context)
+ # Loads "tabtitle" for this admin page so that on render the
+ # element will only have the model name instead of
+ # the default string loaded by native Django admin code.
+ # (Eg. instead of "Select contact to change", display "Contacts")
+ # see "base_site.html" for the code.
+ def changelist_view(self, request, extra_context=None):
+ if extra_context is None:
+ extra_context = {}
+ extra_context["tabtitle"] = str(self.opts.verbose_name_plural).title()
+ # Get the filtered values
+ return super().changelist_view(request, extra_context=extra_context)
+
class HostIPInline(admin.StackedInline):
"""Edit an ip address on the host page."""
@@ -1053,14 +1094,6 @@ class MyHostAdmin(AuditedAdmin, ImportExportModelAdmin):
search_help_text = "Search by domain or host name."
inlines = [HostIPInline]
- # Select host to change -> Host
- def changelist_view(self, request, extra_context=None):
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "Host"
- # Get the filtered values
- return super().changelist_view(request, extra_context=extra_context)
-
class HostIpResource(resources.ModelResource):
"""defines how each field in the referenced model should be mapped to the corresponding fields in the
@@ -1076,14 +1109,6 @@ class HostIpAdmin(AuditedAdmin, ImportExportModelAdmin):
resource_classes = [HostIpResource]
model = models.HostIP
- # Select host ip to change -> Host ip
- def changelist_view(self, request, extra_context=None):
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "Host IP"
- # Get the filtered values
- return super().changelist_view(request, extra_context=extra_context)
-
class ContactResource(resources.ModelResource):
"""defines how each field in the referenced model should be mapped to the corresponding fields in the
@@ -1205,14 +1230,6 @@ class ContactAdmin(ListHeaderAdmin, ImportExportModelAdmin):
return super().change_view(request, object_id, form_url, extra_context=extra_context)
- # Select contact to change -> Contacts
- def changelist_view(self, request, extra_context=None):
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "Contacts"
- # Get the filtered values
- return super().changelist_view(request, extra_context=extra_context)
-
def save_model(self, request, obj, form, change):
# Clear warning messages before saving
storage = messages.get_messages(request)
@@ -1527,14 +1544,6 @@ class DomainInvitationAdmin(BaseInvitationAdmin):
# Override for the delete confirmation page on the domain table (bulk delete action)
delete_selected_confirmation_template = "django/admin/domain_invitation_delete_selected_confirmation.html"
- # Select domain invitations to change -> Domain invitations
- def changelist_view(self, request, extra_context=None):
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "Domain invitations"
- # Get the filtered values
- return super().changelist_view(request, extra_context=extra_context)
-
def change_view(self, request, object_id, form_url="", extra_context=None):
"""Override the change_view to add the invitation obj for the change_form_object_tools template"""
@@ -1673,14 +1682,6 @@ class PortfolioInvitationAdmin(BaseInvitationAdmin):
change_form_template = "django/admin/portfolio_invitation_change_form.html"
delete_confirmation_template = "django/admin/portfolio_invitation_delete_confirmation.html"
- # Select portfolio invitations to change -> Portfolio invitations
- def changelist_view(self, request, extra_context=None):
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "Portfolio invitations"
- # Get the filtered values
- return super().changelist_view(request, extra_context=extra_context)
-
def save_model(self, request, obj, form, change):
"""
Override the save_model method.
@@ -2070,14 +2071,6 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin):
readonly_fields.extend([field for field in self.analyst_readonly_fields])
return readonly_fields # Read-only fields for analysts
- # Select domain information to change -> Domain information
- def changelist_view(self, request, extra_context=None):
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "Domain information"
- # Get the filtered values
- return super().changelist_view(request, extra_context=extra_context)
-
def formfield_for_foreignkey(self, db_field, request, **kwargs):
"""Customize the behavior of formfields with foreign key relationships. This will customize
the behavior of selects. Customized behavior includes sorting of objects in list."""
@@ -2898,11 +2891,6 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
if next_char.isdigit():
should_apply_default_filter = True
- # Select domain request to change -> Domain requests
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "Domain requests"
-
if should_apply_default_filter:
# modify the GET of the request to set the selected filter
modified_get = copy.deepcopy(request.GET)
@@ -3959,14 +3947,6 @@ class DraftDomainAdmin(ListHeaderAdmin, ImportExportModelAdmin):
# If no redirection is needed, return the original response
return response
- # Select draft domain to change -> Draft domains
- def changelist_view(self, request, extra_context=None):
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "Draft domains"
- # Get the filtered values
- return super().changelist_view(request, extra_context=extra_context)
-
class PublicContactResource(resources.ModelResource):
"""defines how each field in the referenced model should be mapped to the corresponding fields in the
@@ -4388,14 +4368,6 @@ class UserGroupAdmin(AuditedAdmin):
def user_group(self, obj):
return obj.name
- # Select user groups to change -> User groups
- def changelist_view(self, request, extra_context=None):
- if extra_context is None:
- extra_context = {}
- extra_context["tabtitle"] = "User groups"
- # Get the filtered values
- return super().changelist_view(request, extra_context=extra_context)
-
class WaffleFlagAdmin(FlagAdmin):
"""Custom admin implementation of django-waffle's Flag class"""
@@ -4412,6 +4384,13 @@ class WaffleFlagAdmin(FlagAdmin):
if extra_context is None:
extra_context = {}
extra_context["dns_prototype_flag"] = flag_is_active_for_user(request.user, "dns_prototype_flag")
+
+ # Loads "tabtitle" for this admin page so that on render the
+ # element will only have the model name instead of
+ # the default string loaded by native Django admin code.
+ # (Eg. instead of "Select waffle flags to change", display "Waffle Flags")
+ # see "base_site.html" for the code.
+ extra_context["tabtitle"] = str(self.opts.verbose_name_plural).title()
return super().changelist_view(request, extra_context=extra_context)
diff --git a/src/registrar/assets/src/sass/_theme/_accordions.scss b/src/registrar/assets/src/sass/_theme/_accordions.scss
index 86b8779ab..a4376337d 100644
--- a/src/registrar/assets/src/sass/_theme/_accordions.scss
+++ b/src/registrar/assets/src/sass/_theme/_accordions.scss
@@ -25,7 +25,6 @@
// Note, width is determined by a custom width class on one of the children
position: absolute;
z-index: 1;
- left: 0;
border-radius: 4px;
border: solid 1px color('base-lighter');
padding: units(2) units(2) units(3) units(2);
@@ -42,6 +41,14 @@
}
}
+// This will work in responsive tables if we overwrite the overflow value on the table container
+// Works with styles in _tables
+@include at-media(desktop) {
+ .usa-accordion--more-actions .usa-accordion__content {
+ left: 0;
+ }
+}
+
.usa-accordion--select .usa-accordion__content {
top: 33.88px;
}
@@ -59,10 +66,12 @@
// This won't work on the Members table rows because that table has show-more rows
// Currently, that's not an issue since that Members table is not wrapped in the
// reponsive wrapper.
-tr:last-of-type .usa-accordion--more-actions .usa-accordion__content {
- top: auto;
- bottom: -10px;
- right: 30px;
+@include at-media-max("desktop") {
+ tr:last-of-type .usa-accordion--more-actions .usa-accordion__content {
+ top: auto;
+ bottom: -10px;
+ right: 30px;
+ }
}
// A CSS only show-more/show-less based on usa-accordion
diff --git a/src/registrar/assets/src/sass/_theme/_base.scss b/src/registrar/assets/src/sass/_theme/_base.scss
index 9a1c5d12b..1442acf1f 100644
--- a/src/registrar/assets/src/sass/_theme/_base.scss
+++ b/src/registrar/assets/src/sass/_theme/_base.scss
@@ -226,11 +226,6 @@ abbr[title] {
}
}
-// Boost this USWDS utility class for the accordions in the portfolio requests table
-.left-auto {
- left: auto!important;
-}
-
.usa-banner__inner--widescreen {
max-width: $widescreen-max-width;
}
diff --git a/src/registrar/assets/src/sass/_theme/_tables.scss b/src/registrar/assets/src/sass/_theme/_tables.scss
index 0e3118126..222f44fcc 100644
--- a/src/registrar/assets/src/sass/_theme/_tables.scss
+++ b/src/registrar/assets/src/sass/_theme/_tables.scss
@@ -152,3 +152,12 @@ th {
.usa-table--full-borderless th {
border: none !important;
}
+
+// This is an override to overflow on certain tables (note the custom class)
+// so that a popup menu can appear and starddle the edge of the table on large
+// screen sizes. Works with styles in _accordions
+@include at-media(desktop) {
+ .usa-table-container--scrollable.usa-table-container--override-overflow {
+ overflow-y: visible;
+ }
+}
diff --git a/src/registrar/templates/admin/analytics.html b/src/registrar/templates/admin/analytics.html
index fdebff22c..44578cd59 100644
--- a/src/registrar/templates/admin/analytics.html
+++ b/src/registrar/templates/admin/analytics.html
@@ -2,6 +2,10 @@
{% load static %}
{% load i18n %}
+{% block title %}
+ Registrar Analytics | Django admin
+{% endblock %}
+
{% block content_title %}Registrar Analytics
{% endblock %}
{% block breadcrumbs %}
diff --git a/src/registrar/templates/admin/base_site.html b/src/registrar/templates/admin/base_site.html
index a8ef438f9..9b7bb5887 100644
--- a/src/registrar/templates/admin/base_site.html
+++ b/src/registrar/templates/admin/base_site.html
@@ -33,8 +33,8 @@
{{ tabtitle }} |
{% else %}
{{ title }} |
- {% endif %}
- {{ site_title|default:_('Django site admin') }}
+ {% endif %}
+ Django admin
{% endblock %}
{% block extrastyle %}{{ block.super }}
diff --git a/src/registrar/templates/domain_org_name_address.html b/src/registrar/templates/domain_org_name_address.html
index 0785b6da1..956ec084b 100644
--- a/src/registrar/templates/domain_org_name_address.html
+++ b/src/registrar/templates/domain_org_name_address.html
@@ -29,7 +29,10 @@
{% csrf_token %}
{% if domain.domain_info.generic_org_type == 'federal' %}
- {% input_with_errors form.federal_agency %}
+ Federal Agency
+
+ {{ domain.domain_info.federal_agency }}
+
{% endif %}
{% input_with_errors form.organization_name %}
diff --git a/src/registrar/templates/includes/domain_requests_table.html b/src/registrar/templates/includes/domain_requests_table.html
index 8adc0929a..df6b12828 100644
--- a/src/registrar/templates/includes/domain_requests_table.html
+++ b/src/registrar/templates/includes/domain_requests_table.html
@@ -163,7 +163,7 @@
{% endif %}
-
+
Your domain requests
diff --git a/src/registrar/templates/includes/domains_table.html b/src/registrar/templates/includes/domains_table.html
index 3cf04a830..f7e47bbbc 100644
--- a/src/registrar/templates/includes/domains_table.html
+++ b/src/registrar/templates/includes/domains_table.html
@@ -198,7 +198,7 @@
-
+
Your registered domains
diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py
index 80a98fc80..940fe29bf 100644
--- a/src/registrar/tests/test_views_domain.py
+++ b/src/registrar/tests/test_views_domain.py
@@ -2088,62 +2088,6 @@ class TestDomainOrganization(TestDomainOverview):
# Check for the value we want to update
self.assertContains(success_result_page, "Faketown")
- @less_console_noise_decorator
- def test_domain_org_name_address_form_federal(self):
- """
- Submitting a change to federal_agency is blocked for federal domains
- """
-
- fed_org_type = DomainInformation.OrganizationChoices.FEDERAL
- self.domain_information.generic_org_type = fed_org_type
- self.domain_information.save()
- try:
- federal_agency, _ = FederalAgency.objects.get_or_create(agency="AMTRAK")
- self.domain_information.federal_agency = federal_agency
- self.domain_information.save()
- except ValueError as err:
- self.fail(f"A ValueError was caught during the test: {err}")
-
- self.assertEqual(self.domain_information.generic_org_type, fed_org_type)
-
- org_name_page = self.app.get(reverse("domain-org-name-address", kwargs={"domain_pk": self.domain.id}))
-
- form = org_name_page.forms[0]
- # Check the value of the input field
- agency_input = form.fields["federal_agency"][0]
- self.assertEqual(agency_input.value, str(federal_agency.id))
-
- # Check if the input field is disabled
- self.assertTrue("disabled" in agency_input.attrs)
- self.assertEqual(agency_input.attrs.get("disabled"), "")
-
- session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
-
- org_name_page.form["federal_agency"] = FederalAgency.objects.filter(agency="Department of State").get().id
- org_name_page.form["city"] = "Faketown"
-
- self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
-
- # Make the change. The agency should be unchanged, but city should be modifiable.
- success_result_page = org_name_page.form.submit()
- self.assertEqual(success_result_page.status_code, 200)
-
- # Check that the agency has not changed
- self.assertEqual(self.domain_information.federal_agency.agency, "AMTRAK")
-
- # Do another check on the form itself
- form = success_result_page.forms[0]
- # Check the value of the input field
- organization_name_input = form.fields["federal_agency"][0]
- self.assertEqual(organization_name_input.value, str(federal_agency.id))
-
- # Check if the input field is disabled
- self.assertTrue("disabled" in organization_name_input.attrs)
- self.assertEqual(organization_name_input.attrs.get("disabled"), "")
-
- # Check for the value we want to update
- self.assertContains(success_result_page, "Faketown")
-
@less_console_noise_decorator
def test_federal_agency_submit_blocked(self):
"""