Skip to content

Commit

Permalink
Merge pull request #1003 from cisagov/rjm/937-admin-ux-review
Browse files Browse the repository at this point in the history
1000 admin ux audit implementation of quick fixes
  • Loading branch information
rachidatecs authored Sep 12, 2023
2 parents e91eff7 + 7bf5814 commit c6670bd
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 15 deletions.
149 changes: 139 additions & 10 deletions src/registrar/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,36 @@
from django.urls import reverse
from registrar.models.utility.admin_sort_fields import AdminSortFields
from . import models
from auditlog.models import LogEntry # type: ignore
from auditlog.admin import LogEntryAdmin # type: ignore

logger = logging.getLogger(__name__)


class CustomLogEntryAdmin(LogEntryAdmin):
"""Overwrite the generated LogEntry admin class"""

list_display = [
"created",
"resource",
"action",
"msg_short",
"user_url",
]

# 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.
def resource(self, obj):
# Return the field value without a link
return f"{obj.content_type} - {obj.object_repr}"

search_help_text = "Search by resource, changes, or user."

change_form_template = "admin/change_form_no_submit.html"
add_form_template = "admin/change_form_no_submit.html"


class AuditedAdmin(admin.ModelAdmin, AdminSortFields):
"""Custom admin to make auditing easier."""

Expand Down Expand Up @@ -91,14 +117,12 @@ def get_filters(self, request):


class UserContactInline(admin.StackedInline):

"""Edit a user's profile on the user page."""

model = models.Contact


class MyUserAdmin(BaseUserAdmin):

"""Custom user admin class to use our inlines."""

inlines = [UserContactInline]
Expand Down Expand Up @@ -152,23 +176,37 @@ def get_fieldsets(self, request, obj=None):


class HostIPInline(admin.StackedInline):

"""Edit an ip address on the host page."""

model = models.HostIP


class MyHostAdmin(AuditedAdmin):

"""Custom host admin class to use our inlines."""

inlines = [HostIPInline]


class DomainAdmin(ListHeaderAdmin):

"""Custom domain admin class to add extra buttons."""

# Columns
list_display = [
"name",
"organization_type",
"state",
]

def organization_type(self, obj):
return obj.domain_info.organization_type

organization_type.admin_order_field = ( # type: ignore
"domain_info__organization_type"
)

# Filters
list_filter = ["domain_info__organization_type"]

search_fields = ["name"]
search_help_text = "Search by domain name."
change_form_template = "django/admin/domain_change_form.html"
Expand Down Expand Up @@ -250,11 +288,100 @@ class ContactAdmin(ListHeaderAdmin):

search_fields = ["email", "first_name", "last_name"]
search_help_text = "Search by firstname, lastname or email."
list_display = [
"contact",
"email",
]

# We name the custom prop 'contact' because linter
# is not allowing a short_description attr on it
# This gets around the linter limitation, for now.
def contact(self, obj: models.Contact):
"""Duplicate the contact _str_"""
if obj.first_name or obj.last_name:
return obj.get_formatted_name()
elif obj.email:
return obj.email
elif obj.pk:
return str(obj.pk)
else:
return ""

contact.admin_order_field = "first_name" # type: ignore


class WebsiteAdmin(ListHeaderAdmin):
"""Custom website admin class."""

# Search
search_fields = [
"website",
]
search_help_text = "Search by website."


class UserDomainRoleAdmin(ListHeaderAdmin):
"""Custom domain role admin class."""

# Columns
list_display = [
"user",
"domain",
"role",
]

# Search
search_fields = [
"user__first_name",
"user__last_name",
"domain__name",
"role",
]
search_help_text = "Search by user, domain, or role."


class DomainInvitationAdmin(ListHeaderAdmin):
"""Custom domain invitation admin class."""

# Columns
list_display = [
"email",
"domain",
"status",
]

# Search
search_fields = [
"email",
"domain__name",
]
search_help_text = "Search by email or domain."


class DomainInformationAdmin(ListHeaderAdmin):
"""Customize domain information admin class."""

# Columns
list_display = [
"domain",
"organization_type",
"created_at",
"submitter",
]

# Filters
list_filter = ["organization_type"]

# Search
search_fields = [
"domain__name",
]
search_help_text = "Search by domain."


class DomainApplicationAdmin(ListHeaderAdmin):

"""Customize the applications listing view."""
"""Custom domain applications admin class."""

# Set multi-selects 'read-only' (hide selects and show data)
# based on user perms and application creator's status
Expand Down Expand Up @@ -428,14 +555,16 @@ def change_view(self, request, object_id, form_url="", extra_context=None):
return super().change_view(request, object_id, form_url, extra_context)


admin.site.unregister(LogEntry) # Unregister the default registration
admin.site.register(LogEntry, CustomLogEntryAdmin)
admin.site.register(models.User, MyUserAdmin)
admin.site.register(models.UserDomainRole, AuditedAdmin)
admin.site.register(models.UserDomainRole, UserDomainRoleAdmin)
admin.site.register(models.Contact, ContactAdmin)
admin.site.register(models.DomainInvitation, AuditedAdmin)
admin.site.register(models.DomainInformation, AuditedAdmin)
admin.site.register(models.DomainInvitation, DomainInvitationAdmin)
admin.site.register(models.DomainInformation, DomainInformationAdmin)
admin.site.register(models.Domain, DomainAdmin)
admin.site.register(models.Host, MyHostAdmin)
admin.site.register(models.Nameserver, MyHostAdmin)
admin.site.register(models.Website, AuditedAdmin)
admin.site.register(models.Website, WebsiteAdmin)
admin.site.register(models.DomainApplication, DomainApplicationAdmin)
admin.site.register(models.TransitionDomain, AuditedAdmin)
9 changes: 6 additions & 3 deletions src/registrar/assets/sass/_theme/_admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ html[data-theme="light"] {

// #{$theme-link-color} would interpolate to 'primary', so we use the source value instead
--link-fg: #{$theme-color-primary};
--link-hover-color: #{$theme-color-primary-darker};
--link-hover-color: #{$theme-color-primary};
// $theme-link-visited-color - violet-70v
--link-selected-fg: #54278f;

Expand Down Expand Up @@ -153,9 +153,12 @@ h1, h2, h3 {
padding-top: 20px;
}

// 'Delete button' layout bug
.submit-row a.deletelink {
// Fix django admin button height bugs
.submit-row a.deletelink,
.delete-confirmation form .cancel-link,
.submit-row a.closelink {
height: auto!important;
font-size: 14px;
}

// Keep th from collapsing
Expand Down
2 changes: 1 addition & 1 deletion src/registrar/templates/admin/app_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<div class="app-{{ app.app_label }} module{% if app.app_url in request.path|urlencode %} current-app{% endif %}">
<table>

{# .gov override #}
{# .gov override: add headers #}
<thead>
<tr>
{% if show_changelinks %}
Expand Down
18 changes: 18 additions & 0 deletions src/registrar/templates/admin/base_site.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@
{% load static %}
{% load i18n %}

{% block extrahead %}
<link rel="icon" type="image/png" sizes="32x32"
href="{% static 'img/registrar/favicons/favicon-32.png' %}"
>
<link rel="icon" type="image/png" sizes="192x192"
href="{% static 'img/registrar/favicons/favicon-192.png' %}"
>
<link rel="icon" type="image/svg+xml"
href="{% static 'img/registrar/favicons/favicon.svg' %}"
>
<link rel="shortcut icon" type="image/x-icon"
href="{% static 'img/registrar/favicons/favicon.ico' %}"
>
<link rel="apple-touch-icon" size="180x180"
href="{% static 'img/registrar/favicons/favicon-180.png' %}"
>
{% endblock %}

{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}

{% block extrastyle %}{{ block.super }}
Expand Down
2 changes: 1 addition & 1 deletion src/registrar/templates/admin/change_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
{% endblock %}
</div>
{% endif %}
{% endblock %}
{% endblock %}
20 changes: 20 additions & 0 deletions src/registrar/templates/admin/change_form_no_submit.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends "admin/change_form.html" %}

{% comment %} Replace the Django ul markup with a div. We'll edit the child markup accordingly in change_form_object_tools {% endcomment %}
{% block object-tools %}
{% if change and not is_popup %}
<div class="object-tools">
{% block object-tools-items %}
{{ block.super }}
{% endblock %}
</div>
{% endif %}
{% endblock %}

{% block submit_buttons_top %}
{# Do not render the submit buttons #}
{% endblock %}

{% block submit_buttons_bottom %}
{# Do not render the submit buttons #}
{% endblock %}

0 comments on commit c6670bd

Please sign in to comment.