diff --git a/README.md b/README.md index 0a34037501..bc0db0af61 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,14 @@ This data is not maintained and should not be relied on for any purpose other th `make local.clean` will remove the local environment completely, useful when you want to start fresh. +## Update CSS for admin site + +To change the styling of the admin site, add custom style rules to `solution/ui/regulations/css/admin/custom_admin.css`. + +To see the changes on the admin site, run `make local.collectstatic`. This will update/create the CSS files in the `solution/static-assets/css/admin` directory. + +You will need to restart the local environment to see the changes. The Makefile will automatically move those files to the correct location where `STATIC_ROOT` is defined. This is the location where Django will look for static files. + ## Testing eRegs #### Testing setup diff --git a/solution/backend/resources/admin/internal_resources.py b/solution/backend/resources/admin/internal_resources.py index a38252e1e2..8888e163e9 100644 --- a/solution/backend/resources/admin/internal_resources.py +++ b/solution/backend/resources/admin/internal_resources.py @@ -25,8 +25,8 @@ class InternalLinkForm(AbstractInternalResourceForm): class InternalLinkAdmin(AbstractInternalResourceAdmin): admin_priority = 20 form = InternalLinkForm - list_display = ["date", "document_id", "title", "category", "updated_at", "approved"] - list_display_links = ["date", "document_id", "title", "category", "updated_at", "approved"] + list_display = ["date", "document_id", "title", "category__name", "updated_at", "approved"] + list_display_links = ["date", "document_id", "title", "updated_at"] search_fields = ["date", "document_id", "title", "summary"] fieldsets = [ @@ -47,6 +47,11 @@ class InternalLinkAdmin(AbstractInternalResourceAdmin): }), ] + class Media: + css = { + 'all': ('css/admin/custom_admin.css',) + } + # Override the URL field's help_text for internal links specifically def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj, **kwargs) @@ -63,10 +68,9 @@ class InternalFileForm(AbstractInternalResourceForm): class InternalFileAdmin(AbstractInternalResourceAdmin): admin_priority = 21 form = InternalFileForm - list_display = ["date", "document_id", "title", "category", "updated_at", "approved"] - list_display_links = ["date", "document_id", "title", "category", "updated_at", "approved"] + list_display = ["date", "document_id", "title", "category__name", "updated_at", "approved"] + list_display_links = ["date", "document_id", "title", "updated_at"] search_fields = ["date", "document_id", "title", "summary"] - ordering = ["date", "document_id", "category", "updated_at"] readonly_fields = ["download_file", "file_name", "file_type"] fieldsets = [ @@ -87,6 +91,10 @@ class InternalFileAdmin(AbstractInternalResourceAdmin): }), ] + class Media: + css = { + 'all': ('css/admin/custom_admin.css',) + } # TODO: use presigned URL to upload to S3 directly, bypassing API Gateway restrictions # Easy to follow how to: https://www.hacksoft.io/blog/direct-to-s3-file-upload-with-django # Most of these methods will be rewritten then. diff --git a/solution/backend/resources/admin/public_resources.py b/solution/backend/resources/admin/public_resources.py index e8acfcfa30..41661154db 100644 --- a/solution/backend/resources/admin/public_resources.py +++ b/solution/backend/resources/admin/public_resources.py @@ -30,8 +30,8 @@ class PublicLinkForm(AbstractPublicResourceForm): class PublicLinkAdmin(AbstractPublicResourceAdmin): admin_priority = 10 form = PublicLinkForm - list_display = ["date", "document_id", "title", "category", "updated_at", "approved"] - list_display_links = ["date", "document_id", "title", "category", "updated_at", "approved"] + list_display = ["date", "document_id", "title", "category__name", "updated_at", "approved"] + list_display_links = ["date", "document_id", "title", "updated_at"] search_fields = ["date", "document_id", "title", "url"] fieldsets = [ @@ -52,6 +52,11 @@ class PublicLinkAdmin(AbstractPublicResourceAdmin): }), ] + class Media: + css = { + 'all': ('css/admin/custom_admin.css',) + } + class FederalRegisterLinkForm(AbstractPublicResourceForm): resource_groups = forms.ModelMultipleChoiceField( @@ -81,11 +86,9 @@ class FederalRegisterLinkAdmin(AbstractPublicResourceAdmin): admin_priority = 11 form = FederalRegisterLinkForm list_display = ["date", "document_id", "title", "in_groups", "docket_numbers", "document_number", - "category", "action_type", "updated_at", "approved"] - list_display_links = ["date", "document_id", "title", "in_groups", "docket_numbers", "document_number", - "category", "action_type", "updated_at", "approved"] + "action_type", "updated_at", "approved"] + list_display_links = ["date", "document_id", "title", "docket_numbers", "document_number", "updated_at"] search_fields = ["date", "document_id", "title", "docket_numbers", "document_number", "url"] - fieldsets = [ ("Basics", { "fields": ["url", "title"], @@ -105,6 +108,11 @@ class FederalRegisterLinkAdmin(AbstractPublicResourceAdmin): }), ] + class Media: + css = { + 'all': ('css/admin/custom_admin.css',) + } + def in_groups(self, obj): groups = ", ".join([str(i) for i in obj.resource_groups.all()]) return f"{groups[:20]}..." if len(groups) > 20 else groups diff --git a/solution/backend/resources/admin/resources.py b/solution/backend/resources/admin/resources.py index 2c0f6db975..8102685c3d 100644 --- a/solution/backend/resources/admin/resources.py +++ b/solution/backend/resources/admin/resources.py @@ -39,7 +39,7 @@ class AbstractResourceAdmin(CustomAdminMixin, admin.ModelAdmin): actions = [actions.mark_approved, actions.mark_not_approved, actions.extract_text] filter_horizontal = ["cfr_citations", "subjects"] empty_value_display = "NONE" - ordering = ["-updated_at", "date", "document_id", "category", "-created_at"] + ordering = ["-updated_at"] list_filter = [ "approved", diff --git a/solution/static-assets/requirements.txt b/solution/static-assets/requirements.txt index 8422f22dbf..0ab31f930d 100644 --- a/solution/static-assets/requirements.txt +++ b/solution/static-assets/requirements.txt @@ -3,7 +3,7 @@ pyopenssl>=24,<25 Werkzeug==0.15.5 boto3 django-debug-toolbar -django>=5.0.7 +django>=5.1 requests djangorestframework psycopg2-binary diff --git a/solution/ui/regulations/css/admin/custom_admin.css b/solution/ui/regulations/css/admin/custom_admin.css new file mode 100644 index 0000000000..502fa41fd8 --- /dev/null +++ b/solution/ui/regulations/css/admin/custom_admin.css @@ -0,0 +1,4 @@ +table#result_list tbody tr td { + /* Allow wrapping on all columns*/ + white-space: normal !important; +}