Repository: cisagov/manage.get.gov

Issue:
The cursor styling on hover for the "Cancel" button on the Invitations table is set incorrectly to an arrow.
### Current Behavior

The cursor styling on hover for the "Cancel" button on the Invitations table is set incorrectly to an arrow. It should be a hand.

![image](https://github.com/cisagov/manage.get.gov/assets/144387994/a1719a94-eea7-4ac4-97f2-57d3c7ee01de)


### Expected Behavior

The cursor styling on hover for the "Cancel" button on the Invitations table is set to a hand.

### Steps to Reproduce

1. Log on as Domain manager on manage.get.gov
2. View Invitations table
3. Hover over the "Cancel" button



### Environment

Environment: Stable

### Additional Context

_No response_

### Issue Links

_No response_


Discussion:

Resolving patch:
diff --git a/src/registrar/admin.py b/src/registrar/admin.py
--- a/src/registrar/admin.py
+++ b/src/registrar/admin.py
@@ -979,6 +979,7 @@ class DomainRequestAdmin(ListHeaderAdmin):
     """Custom domain requests admin class."""
 
     form = DomainRequestAdminForm
+    change_form_template = "django/admin/domain_request_change_form.html"
 
     class InvestigatorFilter(admin.SimpleListFilter):
         """Custom investigator filter that only displays users with the manager role"""
@@ -1040,8 +1041,6 @@ def queryset(self, request, queryset):
             if self.value() == "0":
                 return queryset.filter(Q(is_election_board=False) | Q(is_election_board=None))
 
-    change_form_template = "django/admin/domain_request_change_form.html"
-
     # Columns
     list_display = [
         "requested_domain",
diff --git a/src/registrar/templatetags/custom_filters.py b/src/registrar/templatetags/custom_filters.py
--- a/src/registrar/templatetags/custom_filters.py
+++ b/src/registrar/templatetags/custom_filters.py
@@ -62,3 +62,8 @@ def get_organization_long_name(generic_org_type):
         return "Error"
 
     return long_form_type
+
+
+@register.filter(name="has_permission")
+def has_permission(user, permission):
+    return user.has_perm(permission)


Test patch:
diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py
--- a/src/registrar/tests/test_admin.py
+++ b/src/registrar/tests/test_admin.py
@@ -1213,6 +1213,61 @@ def test_save_model_sets_approved_domain(self):
             self.assertEqual(domain_request.requested_domain.name, domain_request.approved_domain.name)
 
     @less_console_noise_decorator
+    def test_sticky_submit_row(self):
+        """Test that the change_form template contains strings indicative of the customization
+        of the sticky submit bar.
+
+        Also test that it does NOT contain a CSS class meant for analysts only when logged in as superuser."""
+
+        # make sure there is no user with this email
+        EMAIL = "mayor@igorville.gov"
+        User.objects.filter(email=EMAIL).delete()
+        self.client.force_login(self.superuser)
+
+        # Create a sample domain request
+        domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+
+        # Create a mock request
+        request = self.client.post("/admin/registrar/domainrequest/{}/change/".format(domain_request.pk))
+
+        # Since we're using client to mock the request, we can only test against
+        # non-interpolated values
+        expected_content = "<strong>Requested domain:</strong>"
+        expected_content2 = '<span class="scroll-indicator"></span>'
+        expected_content3 = '<div class="submit-row-wrapper">'
+        not_expected_content = "submit-row-wrapper--analyst-view>"
+        self.assertContains(request, expected_content)
+        self.assertContains(request, expected_content2)
+        self.assertContains(request, expected_content3)
+        self.assertNotContains(request, not_expected_content)
+
+    @less_console_noise_decorator
+    def test_sticky_submit_row_has_extra_class_for_analysts(self):
+        """Test that the change_form template contains strings indicative of the customization
+        of the sticky submit bar.
+
+        Also test that it DOES contain a CSS class meant for analysts only when logged in as analyst."""
+
+        # make sure there is no user with this email
+        EMAIL = "mayor@igorville.gov"
+        User.objects.filter(email=EMAIL).delete()
+        self.client.force_login(self.staffuser)
+
+        # Create a sample domain request
+        domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+
+        # Create a mock request
+        request = self.client.post("/admin/registrar/domainrequest/{}/change/".format(domain_request.pk))
+
+        # Since we're using client to mock the request, we can only test against
+        # non-interpolated values
+        expected_content = "<strong>Requested domain:</strong>"
+        expected_content2 = '<span class="scroll-indicator"></span>'
+        expected_content3 = '<div class="submit-row-wrapper submit-row-wrapper--analyst-view">'
+        self.assertContains(request, expected_content)
+        self.assertContains(request, expected_content2)
+        self.assertContains(request, expected_content3)
+
     def test_other_contacts_has_readonly_link(self):
         """Tests if the readonly other_contacts field has links"""
 
diff --git a/src/registrar/tests/test_views_application.py b/src/registrar/tests/test_views_request.py
similarity index 100%
rename from src/registrar/tests/test_views_application.py
rename to src/registrar/tests/test_views_request.py