diff --git a/.github/workflows/deploy-sandbox.yaml b/.github/workflows/deploy-sandbox.yaml index 214cf6076..f2b4303d6 100644 --- a/.github/workflows/deploy-sandbox.yaml +++ b/.github/workflows/deploy-sandbox.yaml @@ -25,6 +25,8 @@ jobs: || startsWith(github.head_ref, 'meoward/') || startsWith(github.head_ref, 'bob/') || startsWith(github.head_ref, 'cb/') + || startsWith(github.head_ref, 'hotgov/') + || startsWith(github.head_ref, 'litterbox/') outputs: environment: ${{ steps.var.outputs.environment}} runs-on: "ubuntu-latest" diff --git a/.github/workflows/migrate.yaml b/.github/workflows/migrate.yaml index f5815012c..283380236 100644 --- a/.github/workflows/migrate.yaml +++ b/.github/workflows/migrate.yaml @@ -16,6 +16,8 @@ on: - stable - staging - development + - litterbox + - hotgov - cb - bob - meoward diff --git a/.github/workflows/reset-db.yaml b/.github/workflows/reset-db.yaml index 06638aa05..b9393415b 100644 --- a/.github/workflows/reset-db.yaml +++ b/.github/workflows/reset-db.yaml @@ -16,6 +16,8 @@ on: options: - staging - development + - litterbox + - hotgov - cb - bob - meoward diff --git a/ops/manifests/manifest-hotgov.yaml b/ops/manifests/manifest-hotgov.yaml new file mode 100644 index 000000000..70cc97ee7 --- /dev/null +++ b/ops/manifests/manifest-hotgov.yaml @@ -0,0 +1,32 @@ +--- +applications: +- name: getgov-hotgov + buildpacks: + - python_buildpack + path: ../../src + instances: 1 + memory: 512M + stack: cflinuxfs4 + timeout: 180 + command: ./run.sh + health-check-type: http + health-check-http-endpoint: /health + health-check-invocation-timeout: 40 + env: + # Send stdout and stderr straight to the terminal without buffering + PYTHONUNBUFFERED: yup + # Tell Django where to find its configuration + DJANGO_SETTINGS_MODULE: registrar.config.settings + # Tell Django where it is being hosted + DJANGO_BASE_URL: https://getgov-hotgov.app.cloud.gov + # Tell Django how much stuff to log + DJANGO_LOG_LEVEL: INFO + # default public site location + GETGOV_PUBLIC_SITE_URL: https://get.gov + # Flag to disable/enable features in prod environments + IS_PRODUCTION: False + routes: + - route: getgov-hotgov.app.cloud.gov + services: + - getgov-credentials + - getgov-hotgov-database diff --git a/ops/manifests/manifest-litterbox.yaml b/ops/manifests/manifest-litterbox.yaml new file mode 100644 index 000000000..ae899ef3a --- /dev/null +++ b/ops/manifests/manifest-litterbox.yaml @@ -0,0 +1,32 @@ +--- +applications: +- name: getgov-litterbox + buildpacks: + - python_buildpack + path: ../../src + instances: 1 + memory: 512M + stack: cflinuxfs4 + timeout: 180 + command: ./run.sh + health-check-type: http + health-check-http-endpoint: /health + health-check-invocation-timeout: 40 + env: + # Send stdout and stderr straight to the terminal without buffering + PYTHONUNBUFFERED: yup + # Tell Django where to find its configuration + DJANGO_SETTINGS_MODULE: registrar.config.settings + # Tell Django where it is being hosted + DJANGO_BASE_URL: https://getgov-litterbox.app.cloud.gov + # Tell Django how much stuff to log + DJANGO_LOG_LEVEL: INFO + # default public site location + GETGOV_PUBLIC_SITE_URL: https://get.gov + # Flag to disable/enable features in prod environments + IS_PRODUCTION: False + routes: + - route: getgov-litterbox.app.cloud.gov + services: + - getgov-credentials + - getgov-litterbox-database diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 22022dd94..6063f6bfc 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -383,6 +383,39 @@ 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: + # extra_context = {} + + # log_entry = self.get_object(request, object_id) + + # if log_entry: + # # Reset title to empty string + # extra_context["subtitle"] = "" + # extra_context["tabtitle"] = "" + + # object_repr = log_entry.object_repr # Hold name of the object + # changes = log_entry.changes + + # # Check if this is a log entry for an addition and related to the contact model + # # Created [name] -> Created [name] contact | Change log entry + # if ( + # all(new_value != "None" for field, (old_value, new_value) in changes.items()) + # and log_entry.content_type.model == "contact" + # ): + # extra_context["subtitle"] = f"Created {object_repr} contact" + # extra_context["tabtitle"] = "Change log entry" + + # return super().change_view(request, object_id, form_url, extra_context=extra_context) + class AdminSortFields: _name_sort = ["first_name", "last_name", "email"] @@ -778,6 +811,14 @@ 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 @@ -793,6 +834,14 @@ 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 @@ -926,6 +975,14 @@ 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) + class WebsiteResource(resources.ModelResource): """defines how each field in the referenced model should be mapped to the corresponding fields in the @@ -1043,6 +1100,21 @@ class UserDomainRoleAdmin(ListHeaderAdmin, ImportExportModelAdmin): else: return response + # User Domain manager [email] is manager on domain [domain name] -> + # Domain manager [email] on [domain name] + def changeform_view(self, request, object_id=None, form_url="", extra_context=None): + if extra_context is None: + extra_context = {} + + if object_id: + obj = self.get_object(request, object_id) + if obj: + email = obj.user.email + domain_name = obj.domain.name + extra_context["subtitle"] = f"Domain manager {email} on {domain_name}" + + return super().changeform_view(request, object_id, form_url, extra_context=extra_context) + class DomainInvitationAdmin(ListHeaderAdmin): """Custom domain invitation admin class.""" @@ -1079,6 +1151,14 @@ class DomainInvitationAdmin(ListHeaderAdmin): change_form_template = "django/admin/email_clipboard_change_form.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) + class DomainInformationResource(resources.ModelResource): """defines how each field in the referenced model should be mapped to the corresponding fields in the @@ -1219,6 +1299,14 @@ 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) + class DomainRequestResource(FsmModelResource): """defines how each field in the referenced model should be mapped to the corresponding fields in the @@ -1674,11 +1762,17 @@ 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) modified_get["status__in"] = "submitted,in review,action needed" request.GET = modified_get + response = super().changelist_view(request, extra_context=extra_context) return response @@ -2244,6 +2338,14 @@ 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 @@ -2288,6 +2390,20 @@ class PublicContactAdmin(ListHeaderAdmin, ImportExportModelAdmin): change_form_template = "django/admin/email_clipboard_change_form.html" autocomplete_fields = ["domain"] + def changeform_view(self, request, object_id=None, form_url="", extra_context=None): + if extra_context is None: + extra_context = {} + + if object_id: + obj = self.get_object(request, object_id) + if obj: + name = obj.name + email = obj.email + registry_id = obj.registry_id + extra_context["subtitle"] = f"{name} <{email}> id: {registry_id}" + + return super().changeform_view(request, object_id, form_url, extra_context=extra_context) + class VerifiedByStaffAdmin(ListHeaderAdmin): list_display = ("email", "requestor", "truncated_notes", "created_at") @@ -2340,6 +2456,14 @@ 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""" diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py index 851f3550c..9a6792dc7 100644 --- a/src/registrar/config/settings.py +++ b/src/registrar/config/settings.py @@ -659,6 +659,8 @@ ALLOWED_HOSTS = [ "getgov-stable.app.cloud.gov", "getgov-staging.app.cloud.gov", "getgov-development.app.cloud.gov", + "getgov-litterbox.app.cloud.gov", + "getgov-hotgov.app.cloud.gov", "getgov-cb.app.cloud.gov", "getgov-bob.app.cloud.gov", "getgov-meoward.app.cloud.gov", diff --git a/src/registrar/templates/admin/base_site.html b/src/registrar/templates/admin/base_site.html index dd680cec5..db34fd893 100644 --- a/src/registrar/templates/admin/base_site.html +++ b/src/registrar/templates/admin/base_site.html @@ -26,10 +26,21 @@ {% endblock %} -{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} +{% block title %} + {% if subtitle %} + {{ subtitle }} | + {% endif %} + {% if tabtitle %} + {{ tabtitle }} | + {% else %} + {{ title }} | + {% endif %} + {{ site_title|default:_('Django site admin') }} +{% endblock %} + {% block extrastyle %}{{ block.super }} -{% endblock %} +{% endblock %} {% block header %} {% if not IS_PRODUCTION %} diff --git a/src/registrar/templates/domain_authorizing_official.html b/src/registrar/templates/domain_authorizing_official.html index aa9808c2e..e5f2f09ba 100644 --- a/src/registrar/templates/domain_authorizing_official.html +++ b/src/registrar/templates/domain_authorizing_official.html @@ -1,7 +1,7 @@ {% extends "domain_base.html" %} {% load static field_helpers url_helpers %} -{% block title %}Domain authorizing official | {{ domain.name }} | {% endblock %} +{% block title %}Authorizing official | {{ domain.name }} | {% endblock %} {% block domain_content %} {# this is right after the messages block in the parent template #} diff --git a/src/registrar/templates/domain_base.html b/src/registrar/templates/domain_base.html index 90c730028..9a869ef42 100644 --- a/src/registrar/templates/domain_base.html +++ b/src/registrar/templates/domain_base.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% load static %} -{% block title %}Domain: {{ domain.name }} | {% endblock %} +{% block title %}{{ domain.name }} | {% endblock %} {% block content %}
diff --git a/src/registrar/templates/domain_request_intro.html b/src/registrar/templates/domain_request_intro.html index 285777a80..2bfeeeef1 100644 --- a/src/registrar/templates/domain_request_intro.html +++ b/src/registrar/templates/domain_request_intro.html @@ -1,6 +1,8 @@ {% extends 'base.html' %} {% load static form_helpers url_helpers %} +{% block title %} Start a request | {% endblock %} + {% block content %}
diff --git a/src/registrar/templates/includes/gov_extended_logo.html b/src/registrar/templates/includes/gov_extended_logo.html index f08aa2c85..be6aba16b 100644 --- a/src/registrar/templates/includes/gov_extended_logo.html +++ b/src/registrar/templates/includes/gov_extended_logo.html @@ -3,7 +3,7 @@