Skip to content

Commit

Permalink
Merge pull request #5222 from FireLemons/javascript_overhaul
Browse files Browse the repository at this point in the history
Javascript overhaul: case_contact.js
  • Loading branch information
FireLemons authored Sep 23, 2023
2 parents 5e65c9f + 63244e1 commit 51f54da
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 126 deletions.
17 changes: 2 additions & 15 deletions app/javascript/__tests__/case_contact.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,6 @@ import { validateOccurredAt, convertDateToSystemTimeZone } from '../src/case_con

require('jest')

test("case_contact doesn't run on pages without case contact form", () => {
// Set up our document body
const name = 'hello'

document.body.innerHTML = `<div>${name}</div>`

require('../src/case_contact')

expect(() => {
window.onload()
}).not.toThrow()
})

test("occured date field won't allow future dates and it will be set back to the current date", () => {
const today = new Date()
const afterTomorrow = new Date(Date.now() + 3600 * 1000 * 24 * 2)
Expand All @@ -29,11 +16,11 @@ test("occured date field won't allow future dates and it will be set back to the

document.body.innerHTML = `<input value="${afterTomorrowString}" data-provide="datepicker" data-date-format="yyyy/mm/dd" class="form-control label-font-weight" type="text" name="case_contact[occurred_at]" id="case_contact_occurred_at">`

const caseOccurredAt = document.getElementById('case_contact_occurred_at')
const caseOccurredAt = $('#case_contact_occurred_at')

validateOccurredAt(caseOccurredAt, 'focusout')

expect(caseOccurredAt.value).toEqual(todayString)
expect(caseOccurredAt.val()).toEqual(todayString)
})

test('utc date is correctly converted to system date', () => {
Expand Down
208 changes: 97 additions & 111 deletions app/javascript/src/case_contact.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,77 @@

import Swal from 'sweetalert2'

window.onload = function () {
const milesDriven = document.getElementById('case_contact_miles_driven')
if (!milesDriven) return
function validateOccurredAt (caseOccurredAt, eventType = '') {
const msg = 'Case Contact Occurrences cannot be in the future.'
const today = new Date()
today.setHours(0, 0, 0, 0)

const caseDate = new Date(caseOccurredAt.val())
caseDate.setDate(caseDate.getDate())
caseDate.setHours(0, 0, 0, 0)

if (caseDate > today) {
if (eventType !== 'focusout') {
alert(msg)
}
caseOccurredAt.val(enGBDateString(today))
}
}

function enGBDateString (date) {
return date.toLocaleDateString('en-GB').split('/').reverse().join('-')
}

function convertDateToSystemTimeZone (date) {
return new Date((typeof date === 'string' ? new Date(date) : date))
}

async function displayFollowupAlert () {
const { value: text, isConfirmed } = await fireSwalFollowupAlert()

if (!isConfirmed) return

const params = text ? { note: text } : {}
const caseContactId = this.id.replace('followup-button-', '')

$.post(
`/case_contacts/${caseContactId}/followups`,
params,
() => window.location.reload()
)
}

const durationHours = document.getElementById('case-contact-duration-hours-display')
const durationMinutes = document.getElementById('case-contact-duration-minutes-display')
const caseOccurredAt = document.getElementById('case_contact_occurred_at')
async function fireSwalFollowupAlert () {
const inputLabel = 'Optional: Add a note about what followup is needed.'

return await Swal.fire({
input: 'textarea',
title: inputLabel,
inputPlaceholder: 'Type your note here...',
inputAttributes: { 'aria-label': 'Type your note here' },

showCancelButton: true,
showCloseButton: true,

confirmButtonText: 'Confirm',
confirmButtonColor: '#dc3545',

customClass: {
inputLabel: 'mx-5'
}
})
}

function displayHighlightModal (event) {
event.preventDefault()
$('#caseContactHighlight').modal('show')
}

$(() => { // JQuery's callback for the DOM loading
const milesDriven = $('#case_contact_miles_driven')
const durationHoursElement = $('#case-contact-duration-hours-display')
const durationMinutes = $('#case-contact-duration-minutes-display')
const caseOccurredAt = $('#case_contact_occurred_at')
const caseContactSubmit = $('#case-contact-submit')
const volunteerAddressFieldState = (hide) => {
if (hide) $('.field.volunteer-address').addClass('hide-field')
Expand All @@ -20,7 +84,7 @@ window.onload = function () {
$('.field.volunteer-address input[type=text]').prop('required', !hide)
}

if ($('.want-driving-reimbursement input.form-check-input[type="radio"][value=true]')[0].checked) {
if ($('.want-driving-reimbursement input.form-check-input[type="radio"][value=true]').prop('checked')) {
volunteerAddressFieldState(false)
} else {
volunteerAddressFieldState(true)
Expand All @@ -36,61 +100,54 @@ window.onload = function () {

const timeZoneConvertedDate = enGBDateString(new Date())

if (enGBDateString(convertDateToSystemTimeZone(caseOccurredAt.value)) === timeZoneConvertedDate) {
caseOccurredAt.value = timeZoneConvertedDate
if (enGBDateString(convertDateToSystemTimeZone(caseOccurredAt.val())) === timeZoneConvertedDate) {
caseOccurredAt.val(timeZoneConvertedDate)
}

milesDriven.onchange = function () {
const contactMedium = document.getElementById('case_contact_medium_type').value || '(contact medium not set)'
milesDriven.on('change', () => {
const contactMedium = $('input[name="case_contact[medium_type]"]:checked').val() || '(contact medium not set)'
const contactMediumInPerson = `${contactMedium}` === 'in-person'
if (milesDriven.value > 0 && !contactMediumInPerson) {
alert(`Just checking: you drove ${milesDriven.value} miles for a ${contactMedium} contact?`)
const milesDrivenCount = milesDriven.val()

if (milesDrivenCount > 0 && !contactMediumInPerson) {
alert(`Just checking: you drove ${milesDrivenCount} miles for a ${contactMedium} contact?`)
}
}
})

caseOccurredAt.onchange = function () {
caseOccurredAt.on('change', () => {
validateOccurredAt(caseOccurredAt)
}
})

caseOccurredAt.onfocusout = function () {
caseOccurredAt.on('focusout', () => {
validateOccurredAt(caseOccurredAt, 'focusout')
}

function validateAtLeastOneChecked (elements) {
// convert to Array
const elementsArray = Array.prototype.slice.call(elements)

const numChecked = elementsArray.filter(x => x.checked).length
if (numChecked === 0) {
elementsArray[0].required = true
} else {
elementsArray[0].required = false
}
}
})

function validateDuration () {
const msg = 'Please enter a minimum duration of 15 minutes (even if you spent less time than this).'
const fifteenMinutes = 15
const totalMinutes = durationMinutes.value + durationHours.value * 60
const totalMinutes = durationMinutes.val() + durationHoursElement.val() * 60
const durationMinutesDOMElement = durationMinutes.get(0)

if (totalMinutes < fifteenMinutes) {
durationMinutes.setCustomValidity(msg)
durationMinutesDOMElement.setCustomValidity(msg)
} else {
durationMinutes.setCustomValidity('')
durationMinutesDOMElement.setCustomValidity('')
}

durationMinutesDOMElement.reportValidity()
}

function validateNoteContent (e) {
const noteContent = document.getElementById('case_contact_notes').value
if (noteContent !== '') {
const noteContent = $('#case_contact_notes').val()
if (noteContent) {
e.preventDefault()
$('#confirm-submit').modal('show')
const escapedNoteContent = noteContent.replace(/&/g, '&amp;')
.replace(/>/g, '&gt;')
.replace(/</g, '&lt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&apos;')
document.getElementById('note-content').innerHTML = escapedNoteContent
$('#note-content').html(escapedNoteContent)
}
}

Expand All @@ -99,93 +156,22 @@ window.onload = function () {
})

$('#confirm-submit').on('focus', function () {
document.getElementById('modal-case-contact-submit').disabled = false
$('#modal-case-contact-submit').prop('disabled', false)
})

$('#confirm-submit').on('hide.bs.modal', function () {
caseContactSubmit.prop('disabled', false)
})

const caseContactSubmitFormModal = document.getElementById('modal-case-contact-submit')
caseContactSubmitFormModal.onclick = function () {
const caseContactSubmitFormModal = $('#modal-case-contact-submit')
caseContactSubmitFormModal.on('click', () => {
$('#casa-contact-form').off('submit')
}
})

caseContactSubmit.on('click', function () {
validateAtLeastOneChecked(document.querySelectorAll('.casa-case-id'))
validateAtLeastOneChecked(document.querySelectorAll('.case-contact-contact-type'))

validateDuration()
})
}

function validateOccurredAt (caseOccurredAt, eventType = '') {
const msg = 'Case Contact Occurrences cannot be in the future.'
const today = new Date()
today.setHours(0, 0, 0, 0)

const caseDate = new Date(caseOccurredAt.value)
caseDate.setDate(caseDate.getDate())
caseDate.setHours(0, 0, 0, 0)

if (caseDate > today) {
if (eventType !== 'focusout') {
alert(msg)
}
caseOccurredAt.value = enGBDateString(today)
}
}

function enGBDateString (date) {
return date.toLocaleDateString('en-GB').split('/').reverse().join('-')
}

function convertDateToSystemTimeZone (date) {
return new Date((typeof date === 'string' ? new Date(date) : date))
}

async function displayFollowupAlert () {
const { value: text, isConfirmed } = await fireSwalFollowupAlert()

if (!isConfirmed) return

const params = text ? { note: text } : {}
const caseContactId = this.id.replace('followup-button-', '')

$.post(
`/case_contacts/${caseContactId}/followups`,
params,
() => window.location.reload()
)
}

async function fireSwalFollowupAlert () {
const inputLabel = 'Optional: Add a note about what followup is needed.'

return await Swal.fire({
input: 'textarea',
title: inputLabel,
inputPlaceholder: 'Type your note here...',
inputAttributes: { 'aria-label': 'Type your note here' },

showCancelButton: true,
showCloseButton: true,

confirmButtonText: 'Confirm',
confirmButtonColor: '#dc3545',

customClass: {
inputLabel: 'mx-5'
}
})
}

function displayHighlightModal (event) {
event.preventDefault()
$('#caseContactHighlight').modal('show')
}

$(() => { // JQuery's callback for the DOM loading
$('[data-toggle="tooltip"]').tooltip()
$('.followup-button').on('click', displayFollowupAlert)
$('#open-highlight-modal').on('click', displayHighlightModal)
Expand Down

0 comments on commit 51f54da

Please sign in to comment.