mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-17 10:07:04 +02:00
Merge remote-tracking branch 'origin/main' into nl/2300-Senior-Official-Table
This commit is contained in:
commit
269c8d641d
6 changed files with 155 additions and 117 deletions
|
@ -9,6 +9,7 @@ from django.db.models.functions import Concat, Coalesce
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django_fsm import get_available_FIELD_transitions, FSMField
|
from django_fsm import get_available_FIELD_transitions, FSMField
|
||||||
|
from waffle.decorators import flag_is_active
|
||||||
from django.contrib import admin, messages
|
from django.contrib import admin, messages
|
||||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
|
@ -166,6 +167,9 @@ class DomainRequestAdminForm(forms.ModelForm):
|
||||||
"alternative_domains": NoAutocompleteFilteredSelectMultiple("alternative_domains", False),
|
"alternative_domains": NoAutocompleteFilteredSelectMultiple("alternative_domains", False),
|
||||||
"other_contacts": NoAutocompleteFilteredSelectMultiple("other_contacts", False),
|
"other_contacts": NoAutocompleteFilteredSelectMultiple("other_contacts", False),
|
||||||
}
|
}
|
||||||
|
labels = {
|
||||||
|
"action_needed_reason_email": "Auto-generated email",
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
@ -1522,6 +1526,13 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
custom_election_board.admin_order_field = "is_election_board" # type: ignore
|
custom_election_board.admin_order_field = "is_election_board" # type: ignore
|
||||||
custom_election_board.short_description = "Election office" # type: ignore
|
custom_election_board.short_description = "Election office" # type: ignore
|
||||||
|
|
||||||
|
# This is just a placeholder. This field will be populated in the detail_table_fieldset view.
|
||||||
|
# This is not a field that exists on the model.
|
||||||
|
def status_history(self, obj):
|
||||||
|
return "No changelog to display."
|
||||||
|
|
||||||
|
status_history.short_description = "Status History" # type: ignore
|
||||||
|
|
||||||
# Filters
|
# Filters
|
||||||
list_filter = (
|
list_filter = (
|
||||||
StatusListFilter,
|
StatusListFilter,
|
||||||
|
@ -1548,9 +1559,11 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
"fields": [
|
"fields": [
|
||||||
"portfolio",
|
"portfolio",
|
||||||
"sub_organization",
|
"sub_organization",
|
||||||
|
"status_history",
|
||||||
"status",
|
"status",
|
||||||
"rejection_reason",
|
"rejection_reason",
|
||||||
"action_needed_reason",
|
"action_needed_reason",
|
||||||
|
"action_needed_reason_email",
|
||||||
"investigator",
|
"investigator",
|
||||||
"creator",
|
"creator",
|
||||||
"submitter",
|
"submitter",
|
||||||
|
@ -1630,6 +1643,8 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
"alternative_domains",
|
"alternative_domains",
|
||||||
"is_election_board",
|
"is_election_board",
|
||||||
"federal_agency",
|
"federal_agency",
|
||||||
|
"status_history",
|
||||||
|
"action_needed_reason_email",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Read only that we'll leverage for CISA Analysts
|
# Read only that we'll leverage for CISA Analysts
|
||||||
|
@ -1948,6 +1963,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
extra_context["filtered_audit_log_entries"] = filtered_audit_log_entries
|
extra_context["filtered_audit_log_entries"] = filtered_audit_log_entries
|
||||||
extra_context["action_needed_reason_emails"] = self.get_all_action_needed_reason_emails_as_json(obj)
|
extra_context["action_needed_reason_emails"] = self.get_all_action_needed_reason_emails_as_json(obj)
|
||||||
|
extra_context["has_profile_feature_flag"] = flag_is_active(request, "profile_feature")
|
||||||
|
|
||||||
# Call the superclass method with updated extra_context
|
# Call the superclass method with updated extra_context
|
||||||
return super().change_view(request, object_id, form_url, extra_context)
|
return super().change_view(request, object_id, form_url, extra_context)
|
||||||
|
@ -1978,9 +1994,13 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
template_subject_path = f"emails/action_needed_reasons/{action_needed_reason}_subject.txt"
|
template_subject_path = f"emails/action_needed_reasons/{action_needed_reason}_subject.txt"
|
||||||
subject_template = get_template(template_subject_path)
|
subject_template = get_template(template_subject_path)
|
||||||
|
|
||||||
# Return the content of the rendered views
|
if flag_is_active(None, "profile_feature"): # type: ignore
|
||||||
context = {"domain_request": domain_request}
|
recipient = domain_request.creator
|
||||||
|
else:
|
||||||
|
recipient = domain_request.submitter
|
||||||
|
|
||||||
|
# Return the content of the rendered views
|
||||||
|
context = {"domain_request": domain_request, "recipient": recipient}
|
||||||
return {
|
return {
|
||||||
"subject_text": subject_template.render(context=context),
|
"subject_text": subject_template.render(context=context),
|
||||||
"email_body_text": template.render(context=context),
|
"email_body_text": template.render(context=context),
|
||||||
|
|
|
@ -361,9 +361,12 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
*/
|
*/
|
||||||
(function (){
|
(function (){
|
||||||
let rejectionReasonFormGroup = document.querySelector('.field-rejection_reason')
|
let rejectionReasonFormGroup = document.querySelector('.field-rejection_reason')
|
||||||
|
// This is the "action needed reason" field
|
||||||
let actionNeededReasonFormGroup = document.querySelector('.field-action_needed_reason');
|
let actionNeededReasonFormGroup = document.querySelector('.field-action_needed_reason');
|
||||||
|
// This is the "auto-generated email" field
|
||||||
|
let actionNeededReasonEmailFormGroup = document.querySelector('.field-action_needed_reason_email')
|
||||||
|
|
||||||
if (rejectionReasonFormGroup && actionNeededReasonFormGroup) {
|
if (rejectionReasonFormGroup && actionNeededReasonFormGroup && actionNeededReasonEmailFormGroup) {
|
||||||
let statusSelect = document.getElementById('id_status')
|
let statusSelect = document.getElementById('id_status')
|
||||||
let isRejected = statusSelect.value == "rejected"
|
let isRejected = statusSelect.value == "rejected"
|
||||||
let isActionNeeded = statusSelect.value == "action needed"
|
let isActionNeeded = statusSelect.value == "action needed"
|
||||||
|
@ -371,6 +374,7 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
// Initial handling of rejectionReasonFormGroup display
|
// Initial handling of rejectionReasonFormGroup display
|
||||||
showOrHideObject(rejectionReasonFormGroup, show=isRejected)
|
showOrHideObject(rejectionReasonFormGroup, show=isRejected)
|
||||||
showOrHideObject(actionNeededReasonFormGroup, show=isActionNeeded)
|
showOrHideObject(actionNeededReasonFormGroup, show=isActionNeeded)
|
||||||
|
showOrHideObject(actionNeededReasonEmailFormGroup, show=isActionNeeded)
|
||||||
|
|
||||||
// Listen to change events and handle rejectionReasonFormGroup display, then save status to session storage
|
// Listen to change events and handle rejectionReasonFormGroup display, then save status to session storage
|
||||||
statusSelect.addEventListener('change', function() {
|
statusSelect.addEventListener('change', function() {
|
||||||
|
@ -382,6 +386,7 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
|
|
||||||
isActionNeeded = statusSelect.value == "action needed"
|
isActionNeeded = statusSelect.value == "action needed"
|
||||||
showOrHideObject(actionNeededReasonFormGroup, show=isActionNeeded)
|
showOrHideObject(actionNeededReasonFormGroup, show=isActionNeeded)
|
||||||
|
showOrHideObject(actionNeededReasonEmailFormGroup, show=isActionNeeded)
|
||||||
addOrRemoveSessionBoolean("showActionNeededReason", add=isActionNeeded)
|
addOrRemoveSessionBoolean("showActionNeededReason", add=isActionNeeded)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -398,6 +403,7 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
|
|
||||||
let showActionNeededReason = sessionStorage.getItem("showActionNeededReason") !== null
|
let showActionNeededReason = sessionStorage.getItem("showActionNeededReason") !== null
|
||||||
showOrHideObject(actionNeededReasonFormGroup, show=showActionNeededReason)
|
showOrHideObject(actionNeededReasonFormGroup, show=showActionNeededReason)
|
||||||
|
showOrHideObject(actionNeededReasonEmailFormGroup, show=isActionNeeded)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -421,42 +427,6 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
sessionStorage.removeItem(name);
|
sessionStorage.removeItem(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
let statusSelect = document.getElementById('id_status');
|
|
||||||
|
|
||||||
function moveStatusChangelog(actionNeededReasonFormGroup, statusSelect) {
|
|
||||||
if (!actionNeededReasonFormGroup || !statusSelect) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let flexContainer = actionNeededReasonFormGroup.querySelector('.flex-container');
|
|
||||||
let statusChangelog = document.getElementById('dja-status-changelog');
|
|
||||||
|
|
||||||
// On action needed, show the email that will be sent out
|
|
||||||
let showReasonEmailContainer = document.querySelector("#action_needed_reason_email_readonly")
|
|
||||||
|
|
||||||
// Prepopulate values on page load.
|
|
||||||
if (statusSelect.value === "action needed") {
|
|
||||||
flexContainer.parentNode.insertBefore(statusChangelog, flexContainer.nextSibling);
|
|
||||||
showElement(showReasonEmailContainer);
|
|
||||||
} else {
|
|
||||||
// Move the changelog back to its original location
|
|
||||||
let statusFlexContainer = statusSelect.closest('.flex-container');
|
|
||||||
statusFlexContainer.parentNode.insertBefore(statusChangelog, statusFlexContainer.nextSibling);
|
|
||||||
hideElement(showReasonEmailContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the function on page load
|
|
||||||
moveStatusChangelog(actionNeededReasonFormGroup, statusSelect);
|
|
||||||
|
|
||||||
// Add event listener to handle changes to the selector itself
|
|
||||||
statusSelect.addEventListener('change', function() {
|
|
||||||
moveStatusChangelog(actionNeededReasonFormGroup, statusSelect);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/** An IIFE for toggling the submit bar on domain request forms
|
/** An IIFE for toggling the submit bar on domain request forms
|
||||||
|
@ -552,13 +522,13 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
/** An IIFE that hooks up to the "show email" button.
|
/** An IIFE that hooks to the show/hide button underneath action needed reason.
|
||||||
* which shows the auto generated email on action needed reason.
|
* This shows the auto generated email on action needed reason.
|
||||||
*/
|
*/
|
||||||
(function () {
|
(function () {
|
||||||
let actionNeededReasonDropdown = document.querySelector("#id_action_needed_reason");
|
let actionNeededReasonDropdown = document.querySelector("#id_action_needed_reason");
|
||||||
let actionNeededEmail = document.querySelector("#action_needed_reason_email_view_more");
|
let actionNeededEmail = document.querySelector("#action_needed_reason_email_view_more");
|
||||||
if(actionNeededReasonDropdown && actionNeededEmail && container) {
|
if(actionNeededReasonDropdown && actionNeededEmail) {
|
||||||
// Add a change listener to the action needed reason dropdown
|
// Add a change listener to the action needed reason dropdown
|
||||||
handleChangeActionNeededEmail(actionNeededReasonDropdown, actionNeededEmail);
|
handleChangeActionNeededEmail(actionNeededReasonDropdown, actionNeededEmail);
|
||||||
}
|
}
|
||||||
|
|
|
@ -787,10 +787,16 @@ div.dja__model-description{
|
||||||
color: var(--link-fg);
|
color: var(--link-fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.textarea-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 610px;
|
||||||
|
}
|
||||||
|
|
||||||
.dja-readonly-textarea-container {
|
.dja-readonly-textarea-container {
|
||||||
|
width: 100%;
|
||||||
textarea {
|
textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 610px;
|
max-width: 610px;
|
||||||
resize: none;
|
resize: none;
|
||||||
cursor: auto;
|
cursor: auto;
|
||||||
|
|
||||||
|
@ -827,3 +833,20 @@ div.dja__model-description{
|
||||||
// Many elements in django admin try to override this, so we need !important.
|
// Many elements in django admin try to override this, so we need !important.
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.margin-top-0 {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-top-0 {
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.flex-container {
|
||||||
|
@media screen and (min-width: 700px) and (max-width: 1150px) {
|
||||||
|
&.flex-container--mobile-inline {
|
||||||
|
display: inline !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -32,7 +32,9 @@ https://github.com/django/django/blob/main/django/contrib/admin/templates/admin/
|
||||||
{% for field in line %}
|
{% for field in line %}
|
||||||
<div>
|
<div>
|
||||||
{% if not line.fields|length == 1 and not field.is_readonly %}{{ field.errors }}{% endif %}
|
{% if not line.fields|length == 1 and not field.is_readonly %}{{ field.errors }}{% endif %}
|
||||||
|
{% block flex_container_start %}
|
||||||
<div class="flex-container{% if not line.fields|length == 1 %} fieldBox{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}{% if field.field.is_hidden %} hidden{% endif %}{% elif field.is_checkbox %} checkbox-row{% endif %}">
|
<div class="flex-container{% if not line.fields|length == 1 %} fieldBox{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}{% if field.field.is_hidden %} hidden{% endif %}{% elif field.is_checkbox %} checkbox-row{% endif %}">
|
||||||
|
{% endblock flex_container_start %}
|
||||||
{% if field.is_checkbox %}
|
{% if field.is_checkbox %}
|
||||||
{# .gov override #}
|
{# .gov override #}
|
||||||
{% block field_checkbox %}
|
{% block field_checkbox %}
|
||||||
|
@ -52,7 +54,9 @@ https://github.com/django/django/blob/main/django/contrib/admin/templates/admin/
|
||||||
{% endblock field_other%}
|
{% endblock field_other%}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% block flex_container_end %}
|
||||||
</div>
|
</div>
|
||||||
|
{% endblock flex_container_end %}
|
||||||
|
|
||||||
{% if field.field.help_text %}
|
{% if field.field.help_text %}
|
||||||
{# .gov override #}
|
{# .gov override #}
|
||||||
|
|
|
@ -6,9 +6,85 @@
|
||||||
This is using a custom implementation fieldset.html (see admin/fieldset.html)
|
This is using a custom implementation fieldset.html (see admin/fieldset.html)
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
|
|
||||||
|
{% block flex_container_start %}
|
||||||
|
{% if field.field.name == "status_history" %}
|
||||||
|
<div class="flex-container flex-container--mobile-inline {% if not line.fields|length == 1 %} fieldBox{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}{% if field.field.is_hidden %} hidden{% endif %}{% elif field.is_checkbox %} checkbox-row{% endif %}">
|
||||||
|
{% else %}
|
||||||
|
{% comment %} Default flex container element {% endcomment %}
|
||||||
|
<div class="flex-container{% if not line.fields|length == 1 %} fieldBox{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}{% if field.field.is_hidden %} hidden{% endif %}{% elif field.is_checkbox %} checkbox-row{% endif %}">
|
||||||
|
{% endif %}
|
||||||
|
{% endblock flex_container_start %}
|
||||||
|
|
||||||
{% block field_readonly %}
|
{% block field_readonly %}
|
||||||
{% with all_contacts=original_object.other_contacts.all %}
|
{% with all_contacts=original_object.other_contacts.all %}
|
||||||
{% if field.field.name == "other_contacts" %}
|
{% if field.field.name == "status_history" %}
|
||||||
|
{% if filtered_audit_log_entries %}
|
||||||
|
<div class="readonly">
|
||||||
|
<div class="usa-table-container--scrollable collapse--dgsimple collapsed margin-top-0" tabindex="0">
|
||||||
|
<table class="usa-table usa-table--borderless">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>User</th>
|
||||||
|
<th>Changed at</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for entry in filtered_audit_log_entries %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{% if entry.status %}
|
||||||
|
{{ entry.status|default:"Error" }}
|
||||||
|
{% else %}
|
||||||
|
Error
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if entry.rejection_reason %}
|
||||||
|
- {{ entry.rejection_reason|default:"Error" }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if entry.action_needed_reason %}
|
||||||
|
- {{ entry.action_needed_reason|default:"Error" }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{ entry.actor|default:"Error" }}</td>
|
||||||
|
<td>{{ entry.timestamp|date:"Y-m-d H:i:s" }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="collapse-toggle--dgsimple usa-button usa-button--unstyled margin-top-0">
|
||||||
|
<span>Show details</span>
|
||||||
|
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
||||||
|
<use xlink:href="/public/img/sprite.svg#expand_more"></use>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="readonly">
|
||||||
|
No changelog to display.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% elif field.field.name == "action_needed_reason_email" %}
|
||||||
|
<div class="readonly textarea-wrapper">
|
||||||
|
<div id="action_needed_reason_email_readonly" class="dja-readonly-textarea-container padding-1 margin-top-0 padding-top-0 margin-bottom-1 thin-border collapse--dgsimple collapsed">
|
||||||
|
<label class="max-full" for="action_needed_reason_email_view_more">
|
||||||
|
<strong>Sent to {% if has_profile_feature_flag %}creator{%else%}submitter{%endif%}</strong>
|
||||||
|
</label>
|
||||||
|
<textarea id="action_needed_reason_email_view_more" cols="40" rows="20" class="{% if not original_object.action_needed_reason %}display-none{% endif %}" readonly>
|
||||||
|
{{ original_object.action_needed_reason_email }}
|
||||||
|
</textarea>
|
||||||
|
<p id="no-email-message" class="{% if original_object.action_needed_reason %}display-none{% endif %}">No email will be sent.</p>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="collapse-toggle--dgsimple usa-button usa-button--unstyled margin-top-0 margin-bottom-1 margin-left-1">
|
||||||
|
<span>Show details</span>
|
||||||
|
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
||||||
|
<use xlink:href="/public/img/sprite.svg#expand_more"></use>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{% elif field.field.name == "other_contacts" %}
|
||||||
{% if all_contacts.count > 2 %}
|
{% if all_contacts.count > 2 %}
|
||||||
<div class="readonly">
|
<div class="readonly">
|
||||||
{% for contact in all_contacts %}
|
{% for contact in all_contacts %}
|
||||||
|
@ -68,48 +144,7 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html)
|
||||||
{% endblock field_readonly %}
|
{% endblock field_readonly %}
|
||||||
|
|
||||||
{% block after_help_text %}
|
{% block after_help_text %}
|
||||||
{% if field.field.name == "status" %}
|
{% if field.field.name == "action_needed_reason_email" %}
|
||||||
<div class="flex-container" id="dja-status-changelog">
|
|
||||||
<label aria-label="Status changelog"></label>
|
|
||||||
<div>
|
|
||||||
<div class="usa-table-container--scrollable collapse--dgsimple collapsed" tabindex="0">
|
|
||||||
{% if filtered_audit_log_entries %}
|
|
||||||
<table class="usa-table usa-table--borderless">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Status</th>
|
|
||||||
<th>User</th>
|
|
||||||
<th>Changed at</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{% for entry in filtered_audit_log_entries %}
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
{% if entry.status %}
|
|
||||||
{{ entry.status|default:"Error" }}
|
|
||||||
{% else %}
|
|
||||||
Error
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if entry.rejection_reason %}
|
|
||||||
- {{ entry.rejection_reason|default:"Error" }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if entry.action_needed_reason %}
|
|
||||||
- {{ entry.action_needed_reason|default:"Error" }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>{{ entry.actor|default:"Error" }}</td>
|
|
||||||
<td>{{ entry.timestamp|date:"Y-m-d H:i:s" }}</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% else %}
|
|
||||||
<p>No changelog to display.</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% comment %}
|
{% comment %}
|
||||||
Store the action needed reason emails in a json-based dictionary.
|
Store the action needed reason emails in a json-based dictionary.
|
||||||
This allows us to change the action_needed_reason_email field dynamically, depending on value.
|
This allows us to change the action_needed_reason_email field dynamically, depending on value.
|
||||||
|
@ -122,26 +157,6 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html)
|
||||||
{{ action_needed_reason_emails|safe }}
|
{{ action_needed_reason_emails|safe }}
|
||||||
</script>
|
</script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div id="action_needed_reason_email_readonly" class="dja-readonly-textarea-container padding-1 margin-top-2 thin-border display-none">
|
|
||||||
<label class="max-full" for="action_needed_reason_email_view_more">
|
|
||||||
<strong>Auto-generated email (sent to submitter)</strong>
|
|
||||||
</label>
|
|
||||||
<textarea id="action_needed_reason_email_view_more" cols="40" rows="20" class="{% if not original_object.action_needed_reason %}display-none{% endif %}" readonly>
|
|
||||||
{{ original_object.action_needed_reason_email }}
|
|
||||||
</textarea>
|
|
||||||
<p id="no-email-message" class="{% if original_object.action_needed_reason %}display-none{% endif %}">No email will be sent.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<button type="button" class="collapse-toggle--dgsimple usa-button usa-button--unstyled margin-top-2 margin-bottom-1 margin-left-1">
|
|
||||||
<span>Show details</span>
|
|
||||||
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
|
||||||
<use xlink:href="/public/img/sprite.svg#expand_more"></use>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% elif field.field.name == "creator" %}
|
{% elif field.field.name == "creator" %}
|
||||||
<div class="flex-container tablet:margin-top-2">
|
<div class="flex-container tablet:margin-top-2">
|
||||||
<label aria-label="Creator contact details"></label>
|
<label aria-label="Creator contact details"></label>
|
||||||
|
|
|
@ -2240,6 +2240,8 @@ class TestDomainRequestAdmin(MockEppLib):
|
||||||
"alternative_domains",
|
"alternative_domains",
|
||||||
"is_election_board",
|
"is_election_board",
|
||||||
"federal_agency",
|
"federal_agency",
|
||||||
|
"status_history",
|
||||||
|
"action_needed_reason_email",
|
||||||
"id",
|
"id",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at",
|
"updated_at",
|
||||||
|
@ -2300,6 +2302,8 @@ class TestDomainRequestAdmin(MockEppLib):
|
||||||
"alternative_domains",
|
"alternative_domains",
|
||||||
"is_election_board",
|
"is_election_board",
|
||||||
"federal_agency",
|
"federal_agency",
|
||||||
|
"status_history",
|
||||||
|
"action_needed_reason_email",
|
||||||
"creator",
|
"creator",
|
||||||
"about_your_organization",
|
"about_your_organization",
|
||||||
"requested_domain",
|
"requested_domain",
|
||||||
|
@ -2330,6 +2334,8 @@ class TestDomainRequestAdmin(MockEppLib):
|
||||||
"alternative_domains",
|
"alternative_domains",
|
||||||
"is_election_board",
|
"is_election_board",
|
||||||
"federal_agency",
|
"federal_agency",
|
||||||
|
"status_history",
|
||||||
|
"action_needed_reason_email",
|
||||||
]
|
]
|
||||||
|
|
||||||
self.assertEqual(readonly_fields, expected_fields)
|
self.assertEqual(readonly_fields, expected_fields)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue