mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-19 10:59:21 +02:00
cleanup
This commit is contained in:
parent
cfa1879909
commit
7cc5231cc0
2 changed files with 128 additions and 115 deletions
|
@ -437,23 +437,46 @@ function initializeWidgetOnList(list, parentId) {
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
class CustomizableEmailBase {
|
class CustomizableEmailBase {
|
||||||
constructor(dropdown, textarea, textareaPlaceholder, directEditButton, modalTrigger, modalConfirm, formLabel, lastSentEmailContent, apiUrl, textAreaFormGroup, dropdownFormGroup) {
|
|
||||||
this.dropdown = dropdown;
|
/**
|
||||||
this.textarea = textarea;
|
* @param {Object} config - must contain the following:
|
||||||
this.textareaPlaceholder = textareaPlaceholder;
|
* @property {HTMLElement} dropdown - The dropdown element.
|
||||||
this.directEditButton = directEditButton;
|
* @property {HTMLElement} textarea - The textarea element.
|
||||||
this.modalTrigger = modalTrigger;
|
* @property {HTMLElement} textareaPlaceholder - The placeholder for the textarea.
|
||||||
this.modalConfirm = modalConfirm;
|
* @property {HTMLElement} directEditButton - The button to directly edit the email.
|
||||||
this.formLabel = formLabel;
|
* @property {HTMLElement} modalTrigger - The trigger for the modal.
|
||||||
this.lastSentEmailContent = lastSentEmailContent;
|
* @property {HTMLElement} modalConfirm - The confirm button in the modal.
|
||||||
this.apiUrl = apiUrl;
|
* @property {HTMLElement} formLabel - The label for the form.
|
||||||
|
* @property {HTMLElement} lastSentEmailContent - The last sent email content element.
|
||||||
|
* @property {HTMLElement} textAreaFormGroup - The form group for the textarea.
|
||||||
|
* @property {HTMLElement} dropdownFormGroup - The form group for the dropdown.
|
||||||
|
* @property {string} apiUrl - The API URL for fetching email content.
|
||||||
|
* @property {string} statusToCheck - The status to check against. Used for show/hide on textAreaFormGroup/dropdownFormGroup.
|
||||||
|
* @property {string} sessionVariableName - The session variable name. Used for show/hide on textAreaFormGroup/dropdownFormGroup.
|
||||||
|
* @property {string} apiErrorMessage - The error message that the ajax call returns.
|
||||||
|
*/
|
||||||
|
constructor(config) {
|
||||||
|
this.dropdown = config.dropdown;
|
||||||
|
this.textarea = config.textarea;
|
||||||
|
this.textareaPlaceholder = config.textareaPlaceholder;
|
||||||
|
this.directEditButton = config.directEditButton;
|
||||||
|
this.modalTrigger = config.modalTrigger;
|
||||||
|
this.modalConfirm = config.modalConfirm;
|
||||||
|
this.formLabel = config.formLabel;
|
||||||
|
this.lastSentEmailContent = config.lastSentEmailContent;
|
||||||
|
this.apiUrl = config.apiUrl;
|
||||||
|
this.apiErrorMessage = config.apiErrorMessage;
|
||||||
|
|
||||||
// These fields are hidden/shown on pageload depending on the current status
|
// These fields are hidden/shown on pageload depending on the current status
|
||||||
this.textAreaFormGroup = textAreaFormGroup;
|
this.textAreaFormGroup = config.textAreaFormGroup;
|
||||||
this.dropdownFormGroup = dropdownFormGroup;
|
this.dropdownFormGroup = config.dropdownFormGroup;
|
||||||
this.statusSelect = document.getElementById("id_status");
|
this.statusToCheck = config.statusToCheck;
|
||||||
|
this.sessionVariableName = config.sessionVariableName;
|
||||||
|
|
||||||
|
// Non-configurable variables
|
||||||
|
this.statusSelect = document.getElementById("id_status");
|
||||||
this.domainRequestId = this.dropdown ? document.getElementById("domain_request_id").value : null
|
this.domainRequestId = this.dropdown ? document.getElementById("domain_request_id").value : null
|
||||||
this.initialDropdownValue = this.dropdown ? this.dropdown.value : null;
|
this.initialDropdownValue = this.dropdown ? this.dropdown.value : null;
|
||||||
this.initialEmailValue = this.textarea ? this.textarea.value : null;
|
this.initialEmailValue = this.textarea ? this.textarea.value : null;
|
||||||
|
@ -466,19 +489,19 @@ class CustomizableEmailBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle showing/hiding the related fields on page load.
|
// Handle showing/hiding the related fields on page load.
|
||||||
initializeFormGroups(statusToCheck, sessionVariableName) {
|
initializeFormGroups() {
|
||||||
let isStatus = this.statusSelect.value == statusToCheck;
|
let isStatus = this.statusSelect.value == this.statusToCheck;
|
||||||
|
|
||||||
// Initial handling of these groups.
|
// Initial handling of these groups.
|
||||||
this.updateFormGroupVisibility(isStatus, isStatus);
|
this.updateFormGroupVisibility(isStatus);
|
||||||
|
|
||||||
// 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
|
||||||
this.statusSelect.addEventListener('change', () => {
|
this.statusSelect.addEventListener('change', () => {
|
||||||
// Show the action needed field if the status is what we expect.
|
// Show the action needed field if the status is what we expect.
|
||||||
// Then track if its shown or hidden in our session cache.
|
// Then track if its shown or hidden in our session cache.
|
||||||
isStatus = this.statusSelect.value == statusToCheck;
|
isStatus = this.statusSelect.value == this.statusToCheck;
|
||||||
this.updateFormGroupVisibility(isStatus, isStatus);
|
this.updateFormGroupVisibility(isStatus);
|
||||||
addOrRemoveSessionBoolean(sessionVariableName, isStatus);
|
addOrRemoveSessionBoolean(this.sessionVariableName, isStatus);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen to Back/Forward button navigation and handle rejectionReasonFormGroup display based on session storage
|
// Listen to Back/Forward button navigation and handle rejectionReasonFormGroup display based on session storage
|
||||||
|
@ -488,20 +511,25 @@ class CustomizableEmailBase {
|
||||||
const observer = new PerformanceObserver((list) => {
|
const observer = new PerformanceObserver((list) => {
|
||||||
list.getEntries().forEach((entry) => {
|
list.getEntries().forEach((entry) => {
|
||||||
if (entry.type === "back_forward") {
|
if (entry.type === "back_forward") {
|
||||||
let showTextAreaFormGroup = sessionStorage.getItem(sessionVariableName) !== null;
|
let showTextAreaFormGroup = sessionStorage.getItem(this.sessionVariableName) !== null;
|
||||||
this.updateFormGroupVisibility(showTextAreaFormGroup, showTextAreaFormGroup);
|
this.updateFormGroupVisibility(showTextAreaFormGroup);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
observer.observe({ type: "navigation" });
|
observer.observe({ type: "navigation" });
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFormGroupVisibility(showTextAreaFormGroup, showDropDownFormGroup) {
|
updateFormGroupVisibility(showFormGroups) {
|
||||||
showTextAreaFormGroup ? showElement(this.textAreaFormGroup) : hideElement(this.textAreaFormGroup);
|
if (showFormGroups) {
|
||||||
showDropDownFormGroup ? showElement(this.dropdownFormGroup) : hideElement(this.dropdownFormGroup);
|
showElement(this.textAreaFormGroup);
|
||||||
|
showElement(this.dropdownFormGroup);
|
||||||
|
}else {
|
||||||
|
hideElement(this.textAreaFormGroup);
|
||||||
|
hideElement(this.dropdownFormGroup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeDropdown(errorMessage) {
|
initializeDropdown() {
|
||||||
this.dropdown.addEventListener("change", () => {
|
this.dropdown.addEventListener("change", () => {
|
||||||
let reason = this.dropdown.value;
|
let reason = this.dropdown.value;
|
||||||
if (this.initialDropdownValue !== this.dropdown.value || this.initialEmailValue !== this.textarea.value) {
|
if (this.initialDropdownValue !== this.dropdown.value || this.initialEmailValue !== this.textarea.value) {
|
||||||
|
@ -525,7 +553,7 @@ class CustomizableEmailBase {
|
||||||
this.updateUserInterface(reason);
|
this.updateUserInterface(reason);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(errorMessage, error)
|
console.error(this.apiErrorMessage, error)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -553,7 +581,7 @@ class CustomizableEmailBase {
|
||||||
return this.lastSentEmailContent.value.replace(/\s+/g, '') === this.textarea.value.replace(/\s+/g, '');
|
return this.lastSentEmailContent.value.replace(/\s+/g, '') === this.textarea.value.replace(/\s+/g, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUserInterface(reason) {
|
updateUserInterface(reason=this.dropdown.value) {
|
||||||
if (!reason) {
|
if (!reason) {
|
||||||
// No reason selected, we will set the label to "Email", show the "Make a selection" placeholder, hide the trigger, textarea, hide the help text
|
// No reason selected, we will set the label to "Email", show the "Make a selection" placeholder, hide the trigger, textarea, hide the help text
|
||||||
this.showPlaceholderNoReason();
|
this.showPlaceholderNoReason();
|
||||||
|
@ -611,46 +639,33 @@ class CustomizableEmailBase {
|
||||||
|
|
||||||
class customActionNeededEmail extends CustomizableEmailBase {
|
class customActionNeededEmail extends CustomizableEmailBase {
|
||||||
constructor() {
|
constructor() {
|
||||||
const dropdown = document.getElementById("id_action_needed_reason");
|
const emailConfig = {
|
||||||
const textarea = document.getElementById("id_action_needed_reason_email")
|
dropdown: document.getElementById("id_action_needed_reason"),
|
||||||
const textareaPlaceholder = document.querySelector(".field-action_needed_reason_email__placeholder");
|
textarea: document.getElementById("id_action_needed_reason_email"),
|
||||||
const directEditButton = document.querySelector('.field-action_needed_reason_email__edit');
|
textareaPlaceholder: document.querySelector(".field-action_needed_reason_email__placeholder"),
|
||||||
const modalTrigger = document.querySelector('.field-action_needed_reason_email__modal-trigger');
|
directEditButton: document.querySelector('.field-action_needed_reason_email__edit'),
|
||||||
const modalConfirm = document.getElementById('confirm-edit-email');
|
modalTrigger: document.querySelector('.field-action_needed_reason_email__modal-trigger'),
|
||||||
const formLabel = document.querySelector('label[for="id_action_needed_reason_email"]');
|
modalConfirm: document.getElementById('confirm-edit-email'),
|
||||||
const lastSentEmailContent = document.getElementById("last-sent-action-needed-email-content");
|
formLabel: document.querySelector('label[for="id_action_needed_reason_email"]'),
|
||||||
|
lastSentEmailContent: document.getElementById("last-sent-action-needed-email-content"),
|
||||||
let apiContainer = document.getElementById("get-action-needed-email-for-user-json")
|
apiUrl: document.getElementById("get-action-needed-email-for-user-json")?.value || null,
|
||||||
const apiUrl = apiContainer ? apiContainer.value : null;
|
textAreaFormGroup: document.querySelector('.field-action_needed_reason'),
|
||||||
|
dropdownFormGroup: document.querySelector('.field-action_needed_reason_email'),
|
||||||
// These fields are hidden on pageload
|
statusToCheck: "rejected",
|
||||||
const textAreaFormGroup = document.querySelector('.field-action_needed_reason');
|
sessionVariableName: "showRejectionReason",
|
||||||
const dropdownFormGroup = document.querySelector('.field-action_needed_reason_email');
|
apiErrorMessage: "Error when attempting to grab rejected email: "
|
||||||
|
}
|
||||||
super(
|
super(emailConfig);
|
||||||
dropdown,
|
|
||||||
textarea,
|
|
||||||
textareaPlaceholder,
|
|
||||||
directEditButton,
|
|
||||||
modalTrigger,
|
|
||||||
modalConfirm,
|
|
||||||
formLabel,
|
|
||||||
lastSentEmailContent,
|
|
||||||
apiUrl,
|
|
||||||
textAreaFormGroup,
|
|
||||||
dropdownFormGroup,
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadActionNeededEmail() {
|
loadActionNeededEmail() {
|
||||||
// Hide/show the email fields depending on the current status
|
// Hide/show the email fields depending on the current status
|
||||||
this.initializeFormGroups("action needed", "showActionNeededReason");
|
this.initializeFormGroups();
|
||||||
// Setup the textarea, edit button, helper text
|
// Setup the textarea, edit button, helper text
|
||||||
this.updateUserInterface(this.dropdown.value);
|
this.updateUserInterface();
|
||||||
this.initializeDropdown("Error when attempting to grab action needed email: ")
|
this.initializeDropdown();
|
||||||
this.initializeModalConfirm()
|
this.initializeModalConfirm();
|
||||||
this.initializeDirectEditButton()
|
this.initializeDirectEditButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overrides the placeholder text when no reason is selected
|
// Overrides the placeholder text when no reason is selected
|
||||||
|
@ -681,40 +696,28 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
|
||||||
class customRejectedEmail extends CustomizableEmailBase {
|
class customRejectedEmail extends CustomizableEmailBase {
|
||||||
constructor() {
|
constructor() {
|
||||||
const dropdown = document.getElementById("id_rejection_reason");
|
const emailConfig = {
|
||||||
const textarea = document.getElementById("id_rejection_reason_email")
|
dropdown: document.getElementById("id_rejection_reason"),
|
||||||
const textareaPlaceholder = document.querySelector(".field-rejection_reason_email__placeholder");
|
textarea: document.getElementById("id_rejection_reason_email"),
|
||||||
const directEditButton = document.querySelector('.field-rejection_reason_email__edit');
|
textareaPlaceholder: document.querySelector(".field-rejection_reason_email__placeholder"),
|
||||||
const modalTrigger = document.querySelector('.field-rejection_reason_email__modal-trigger');
|
directEditButton: document.querySelector('.field-rejection_reason_email__edit'),
|
||||||
const modalConfirm = document.getElementById('confirm-edit-email');
|
modalTrigger: document.querySelector('.field-rejection_reason_email__modal-trigger'),
|
||||||
const formLabel = document.querySelector('label[for="id_rejection_reason_email"]');
|
modalConfirm: document.getElementById('confirm-edit-email'),
|
||||||
const lastSentEmailContent = document.getElementById("last-sent-rejection-email-content");
|
formLabel: document.querySelector('label[for="id_rejection_reason_email"]'),
|
||||||
|
lastSentEmailContent: document.getElementById("last-sent-rejection-email-content"),
|
||||||
let apiContainer = document.getElementById("get-rejection-email-for-user-json");
|
apiUrl: document.getElementById("get-rejection-email-for-user-json")?.value || null,
|
||||||
const apiUrl = apiContainer ? apiContainer.value : null;
|
textAreaFormGroup: document.querySelector('.field-rejection_reason'),
|
||||||
|
dropdownFormGroup: document.querySelector('.field-rejection_reason_email'),
|
||||||
// These fields are hidden on pageload
|
statusToCheck: "rejected",
|
||||||
const textAreaFormGroup = document.querySelector('.field-rejection_reason');
|
sessionVariableName: "showRejectionReason",
|
||||||
const dropdownFormGroup = document.querySelector('.field-rejection_reason_email');
|
errorMessage: "Error when attempting to grab rejected email: "
|
||||||
|
};
|
||||||
super(
|
super(emailConfig);
|
||||||
dropdown,
|
|
||||||
textarea,
|
|
||||||
textareaPlaceholder,
|
|
||||||
directEditButton,
|
|
||||||
modalTrigger,
|
|
||||||
modalConfirm,
|
|
||||||
formLabel,
|
|
||||||
lastSentEmailContent,
|
|
||||||
apiUrl,
|
|
||||||
textAreaFormGroup,
|
|
||||||
dropdownFormGroup,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadRejectedEmail() {
|
loadRejectedEmail() {
|
||||||
this.initializeFormGroups("rejected", "showRejectionReason");
|
this.initializeFormGroups("rejected", "showRejectionReason");
|
||||||
this.updateUserInterface(this.dropdown.value);
|
this.updateUserInterface();
|
||||||
this.initializeDropdown("Error when attempting to grab rejected email: ")
|
this.initializeDropdown("Error when attempting to grab rejected email: ")
|
||||||
this.initializeModalConfirm()
|
this.initializeModalConfirm()
|
||||||
this.initializeDirectEditButton()
|
this.initializeDirectEditButton()
|
||||||
|
|
|
@ -661,39 +661,49 @@ class DomainRequest(TimeStampedModel):
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
# Handle the action needed email.
|
# Handle custom status emails.
|
||||||
# An email is sent out when action_needed_reason is changed or added.
|
# An email is sent out when a, for example, action_needed_reason is changed or added.
|
||||||
if self.status == self.DomainRequestStatus.ACTION_NEEDED:
|
statuses_that_send_custom_emails = [self.DomainRequestStatus.ACTION_NEEDED, self.DomainRequestStatus.REJECTED]
|
||||||
self.send_another_status_reason_email(
|
if self.status in statuses_that_send_custom_emails:
|
||||||
checked_status=self.DomainRequestStatus.ACTION_NEEDED,
|
self.send_another_status_reason_email(self.status)
|
||||||
old_reason=self._cached_action_needed_reason,
|
|
||||||
new_reason=self.action_needed_reason,
|
|
||||||
excluded_reasons=[DomainRequest.ActionNeededReasons.OTHER],
|
|
||||||
email_to_send=self.action_needed_reason_email
|
|
||||||
)
|
|
||||||
elif self.status == self.DomainRequestStatus.REJECTED:
|
|
||||||
self.send_another_status_reason_email(
|
|
||||||
checked_status=self.DomainRequestStatus.REJECTED,
|
|
||||||
old_reason=self._cached_rejection_reason,
|
|
||||||
new_reason=self.rejection_reason,
|
|
||||||
excluded_reasons=[DomainRequest.RejectionReasons.OTHER],
|
|
||||||
email_to_send=self.rejection_reason_email,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Update the cached values after saving
|
# Update the cached values after saving
|
||||||
self._cache_status_and_status_reasons()
|
self._cache_status_and_status_reasons()
|
||||||
|
|
||||||
def send_another_status_reason_email(self, checked_status, old_reason, new_reason, excluded_reasons, email_to_send):
|
def send_another_status_reason_email(self, status):
|
||||||
"""Helper function to send out a second status email when the status remains the same,
|
"""Helper function to send out a second status email when the status remains the same,
|
||||||
but the reason has changed."""
|
but the reason has changed."""
|
||||||
|
|
||||||
|
# Currently, we store all this information in three variables.
|
||||||
|
# When adding new reasons, this can be a lot to manage so we store it here
|
||||||
|
# in a centralized location. However, this may need to change if this scales.
|
||||||
|
status_information = {
|
||||||
|
self.DomainRequestStatus.ACTION_NEEDED: {
|
||||||
|
"cached_reason": self._cached_action_needed_reason,
|
||||||
|
"reason": self.action_needed_reason,
|
||||||
|
"email": self.action_needed_reason_email,
|
||||||
|
"excluded_reasons": [DomainRequest.ActionNeededReasons.OTHER],
|
||||||
|
},
|
||||||
|
self.DomainRequestStatus.REJECTED: {
|
||||||
|
"cached_reason": self._cached_rejection_reason,
|
||||||
|
"reason": self.rejection_reason,
|
||||||
|
"email": self.rejection_reason_email,
|
||||||
|
"excluded_reasons": [DomainRequest.RejectionReasons.OTHER],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current_status = status_information.get(status)
|
||||||
|
old_reason = status_information.get("cached_reason")
|
||||||
|
new_reason = status_information.get("reason")
|
||||||
|
email_to_send = status_information.get("email")
|
||||||
|
|
||||||
# If the status itself changed, then we already sent out an email
|
# If the status itself changed, then we already sent out an email
|
||||||
if self._cached_status != checked_status or old_reason is None:
|
if self._cached_status != status or old_reason is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# We should never send an email if no reason was specified
|
# We should never send an email if no reason was specified
|
||||||
# Additionally, Don't send out emails for reasons that shouldn't send them
|
# Additionally, Don't send out emails for reasons that shouldn't send them
|
||||||
if new_reason is None or new_reason in excluded_reasons:
|
if new_reason is None or new_reason in current_status.get("excluded_reasons"):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Only send out an email if the underlying email itself changed
|
# Only send out an email if the underlying email itself changed
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue