/* eslint-disable spaced-comment, @typescript-eslint/no-non-null-assertion, unicorn/prefer-module */
import type * as globalTypes from '../../types/globalTypes'
import type * as recordTypes from '../../types/recordTypes'
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types'
import type { BulmaJS } from '@cityssm/bulma-js/types'
declare const cityssm: cityssmGlobal
declare const bulmaJS: BulmaJS
;(() => {
const los = exports.los as globalTypes.LOS
const lotOccupancyId = (
document.querySelector('#lotOccupancy--lotOccupancyId') as HTMLInputElement
).value
const isCreate = lotOccupancyId === ''
/*
* Main form
*/
let refreshAfterSave = isCreate
const formElement = document.querySelector(
'#form--lotOccupancy'
) as HTMLFormElement
formElement.addEventListener('submit', (formEvent) => {
formEvent.preventDefault()
cityssm.postJSON(
los.urlPrefix +
'/lotOccupancies/' +
(isCreate ? 'doCreateLotOccupancy' : 'doUpdateLotOccupancy'),
formElement,
(responseJSON: {
success: boolean
lotOccupancyId?: number
errorMessage?: string
}) => {
if (responseJSON.success) {
los.clearUnsavedChanges()
if (isCreate || refreshAfterSave) {
window.location.href = los.getLotOccupancyURL(
responseJSON.lotOccupancyId,
true,
true
)
} else {
bulmaJS.alert({
message: `${los.escapedAliases.Occupancy} Updated Successfully`,
contextualColorName: 'success'
})
}
} else {
bulmaJS.alert({
title: 'Error Saving ' + los.escapedAliases.Occupancy,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
})
}
}
)
})
const formInputElements = formElement.querySelectorAll('input, select')
for (const formInputElement of formInputElements) {
formInputElement.addEventListener('change', los.setUnsavedChanges)
}
function doCopy(): void {
cityssm.postJSON(
los.urlPrefix + '/lotOccupancies/doCopyLotOccupancy',
{
lotOccupancyId
},
(responseJSON: {
success: boolean
errorMessage?: string
lotOccupancyId?: number
}) => {
if (responseJSON.success) {
cityssm.disableNavBlocker()
window.location.href = los.getLotOccupancyURL(
responseJSON.lotOccupancyId,
true
)
} else {
bulmaJS.alert({
title: 'Error Copying Record',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
})
}
}
)
}
document
.querySelector('#button--copyLotOccupancy')
?.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault()
if (los.hasUnsavedChanges()) {
bulmaJS.alert({
title: 'Unsaved Changes',
message: 'Please save all unsaved changes before continuing.',
contextualColorName: 'warning'
})
} else {
bulmaJS.confirm({
title: `Copy ${los.escapedAliases.Occupancy} Record as New`,
message: 'Are you sure you want to copy this record to a new record?',
contextualColorName: 'info',
okButton: {
text: 'Yes, Copy',
callbackFunction: doCopy
}
})
}
})
document
.querySelector('#button--deleteLotOccupancy')
?.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault()
function doDelete(): void {
cityssm.postJSON(
los.urlPrefix + '/lotOccupancies/doDeleteLotOccupancy',
{
lotOccupancyId
},
(responseJSON: { success: boolean; errorMessage?: string }) => {
if (responseJSON.success) {
cityssm.disableNavBlocker()
window.location.href = los.getLotOccupancyURL()
} else {
bulmaJS.alert({
title: 'Error Deleting Record',
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
})
}
}
)
}
bulmaJS.confirm({
title: `Delete ${los.escapedAliases.Occupancy} Record`,
message: 'Are you sure you want to delete this record?',
contextualColorName: 'warning',
okButton: {
text: 'Yes, Delete',
callbackFunction: doDelete
}
})
})
document
.querySelector('#button--createWorkOrder')
?.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault()
let createCloseModalFunction: () => void
function doCreate(formEvent: SubmitEvent): void {
formEvent.preventDefault()
cityssm.postJSON(
los.urlPrefix + '/workOrders/doCreateWorkOrder',
formEvent.currentTarget,
(responseJSON: {
success: boolean
errorMessage?: string
workOrderId?: number
}) => {
if (responseJSON.success) {
createCloseModalFunction()
bulmaJS.confirm({
title: 'Work Order Created Successfully',
message: 'Would you like to open the work order now?',
contextualColorName: 'success',
okButton: {
text: 'Yes, Open the Work Order',
callbackFunction: () => {
window.location.href = los.getWorkOrderURL(
responseJSON.workOrderId,
true
)
}
}
})
} else {
bulmaJS.alert({
title: 'Error Creating Work Order',
message: responseJSON.errorMessage as string,
contextualColorName: 'danger'
})
}
}
)
}
cityssm.openHtmlModal('lotOccupancy-createWorkOrder', {
onshow(modalElement) {
;(
modalElement.querySelector(
'#workOrderCreate--lotOccupancyId'
) as HTMLInputElement
).value = lotOccupancyId
;(
modalElement.querySelector(
'#workOrderCreate--workOrderOpenDateString'
) as HTMLInputElement
).value = cityssm.dateToString(new Date())
const workOrderTypeSelectElement = modalElement.querySelector(
'#workOrderCreate--workOrderTypeId'
) as HTMLSelectElement
const workOrderTypes =
exports.workOrderTypes as recordTypes.WorkOrderType[]
if (workOrderTypes.length === 1) {
workOrderTypeSelectElement.innerHTML = ''
}
for (const workOrderType of workOrderTypes) {
const optionElement = document.createElement('option')
optionElement.value = (
workOrderType.workOrderTypeId as number
).toString()
optionElement.textContent = workOrderType.workOrderType as string
workOrderTypeSelectElement.append(optionElement)
}
},
onshown(modalElement, closeModalFunction) {
createCloseModalFunction = closeModalFunction
bulmaJS.toggleHtmlClipped()
modalElement
.querySelector('form')
?.addEventListener('submit', doCreate)
},
onremoved() {
bulmaJS.toggleHtmlClipped()
}
})
})
// Occupancy Type
const occupancyTypeIdElement = document.querySelector(
'#lotOccupancy--occupancyTypeId'
) as HTMLSelectElement
if (isCreate) {
const lotOccupancyFieldsContainerElement = document.querySelector(
'#container--lotOccupancyFields'
) as HTMLElement
occupancyTypeIdElement.addEventListener('change', () => {
if (occupancyTypeIdElement.value === '') {
lotOccupancyFieldsContainerElement.innerHTML = `
Select the ${los.escapedAliases.occupancy} type to load the available fields.
`
return
}
cityssm.postJSON(
los.urlPrefix + '/lotOccupancies/doGetOccupancyTypeFields',
{
occupancyTypeId: occupancyTypeIdElement.value
},
(responseJSON: {
occupancyTypeFields: recordTypes.OccupancyTypeField[]
}) => {
if (responseJSON.occupancyTypeFields.length === 0) {
lotOccupancyFieldsContainerElement.innerHTML = `
There are no additional fields for this ${los.escapedAliases.occupancy} type.
`
return
}
lotOccupancyFieldsContainerElement.innerHTML = ''
let occupancyTypeFieldIds = ''
for (const occupancyTypeField of responseJSON.occupancyTypeFields) {
occupancyTypeFieldIds +=
',' + occupancyTypeField.occupancyTypeFieldId!.toString()
const fieldName =
'lotOccupancyFieldValue_' +
occupancyTypeField.occupancyTypeFieldId!.toString()
const fieldId = 'lotOccupancy--' + fieldName
const fieldElement = document.createElement('div')
fieldElement.className = 'field'
fieldElement.innerHTML = ``
;(
fieldElement.querySelector('label') as HTMLLabelElement
).textContent = occupancyTypeField.occupancyTypeField as string
if (occupancyTypeField.occupancyTypeFieldValues === '') {
const inputElement = document.createElement('input')
inputElement.className = 'input'
inputElement.id = fieldId
inputElement.name = fieldName
inputElement.type = 'text'
inputElement.required = occupancyTypeField.isRequired as boolean
inputElement.minLength =
occupancyTypeField.minimumLength as number
inputElement.maxLength =
occupancyTypeField.maximumLength as number
if ((occupancyTypeField.pattern ?? '') !== '') {
inputElement.pattern = occupancyTypeField.pattern!
}
;(fieldElement.querySelector('.control') as HTMLElement).append(
inputElement
)
} else {
;(
fieldElement.querySelector('.control') as HTMLElement
).innerHTML = `
`
const selectElement = fieldElement.querySelector(
'select'
) as HTMLSelectElement
selectElement.required = occupancyTypeField.isRequired as boolean
const optionValues = (
occupancyTypeField.occupancyTypeFieldValues as string
).split('\n')
for (const optionValue of optionValues) {
const optionElement = document.createElement('option')
optionElement.value = optionValue
optionElement.textContent = optionValue
selectElement.append(optionElement)
}
}
lotOccupancyFieldsContainerElement.append(fieldElement)
}
lotOccupancyFieldsContainerElement.insertAdjacentHTML(
'beforeend',
``
)
}
)
})
} else {
const originalOccupancyTypeId = occupancyTypeIdElement.value
occupancyTypeIdElement.addEventListener('change', () => {
if (occupancyTypeIdElement.value !== originalOccupancyTypeId) {
bulmaJS.confirm({
title: 'Confirm Change',
message: `Are you sure you want to change the ${los.escapedAliases.occupancy} type?\n
This change affects the additional fields associated with this record, and may also affect the available fees.`,
contextualColorName: 'warning',
okButton: {
text: 'Yes, Keep the Change',
callbackFunction: () => {
refreshAfterSave = true
}
},
cancelButton: {
text: 'Revert the Change',
callbackFunction: () => {
occupancyTypeIdElement.value = originalOccupancyTypeId
}
}
})
}
})
}
// Lot Selector
const lotNameElement = document.querySelector(
'#lotOccupancy--lotName'
) as HTMLInputElement
lotNameElement.addEventListener('click', (clickEvent) => {
const currentLotName = (clickEvent.currentTarget as HTMLInputElement).value
let lotSelectCloseModalFunction: () => void
let lotSelectModalElement: HTMLElement
let lotSelectFormElement: HTMLFormElement
let lotSelectResultsElement: HTMLElement
function renderSelectedLotAndClose(
lotId: number | string,
lotName: string
): void {
;(
document.querySelector('#lotOccupancy--lotId') as HTMLInputElement
).value = lotId.toString()
;(
document.querySelector('#lotOccupancy--lotName') as HTMLInputElement
).value = lotName
los.setUnsavedChanges()
lotSelectCloseModalFunction()
}
function selectExistingLot(clickEvent: Event): void {
clickEvent.preventDefault()
const selectedLotElement = clickEvent.currentTarget as HTMLElement
renderSelectedLotAndClose(
selectedLotElement.dataset.lotId!,
selectedLotElement.dataset.lotName!
)
}
function searchLots(): void {
lotSelectResultsElement.innerHTML =
los.getLoadingParagraphHTML('Searching...')
cityssm.postJSON(
los.urlPrefix + '/lots/doSearchLots',
lotSelectFormElement,
(responseJSON: { count: number; lots: recordTypes.Lot[] }) => {
if (responseJSON.count === 0) {
lotSelectResultsElement.innerHTML = ``
return
}
const panelElement = document.createElement('div')
panelElement.className = 'panel'
for (const lot of responseJSON.lots) {
const panelBlockElement = document.createElement('a')
panelBlockElement.className = 'panel-block is-block'
panelBlockElement.href = '#'
panelBlockElement.dataset.lotId = lot.lotId.toString()
panelBlockElement.dataset.lotName = lot.lotName
panelBlockElement.innerHTML =
'' +
('
' +
cityssm.escapeHTML(lot.lotName ?? '') +
'
' +
'' +
cityssm.escapeHTML(lot.mapName ?? '') +
'' +
'
') +
('
' +
cityssm.escapeHTML(lot.lotStatus as string) +
'
' +
'' +
(lot.lotOccupancyCount! > 0 ? 'Currently Occupied' : '') +
'' +
'
') +
'
'
panelBlockElement.addEventListener('click', selectExistingLot)
panelElement.append(panelBlockElement)
}
lotSelectResultsElement.innerHTML = ''
lotSelectResultsElement.append(panelElement)
}
)
}
function createLotAndSelect(submitEvent: SubmitEvent): void {
submitEvent.preventDefault()
const lotName = (
lotSelectModalElement.querySelector(
'#lotCreate--lotName'
) as HTMLInputElement
).value
cityssm.postJSON(
los.urlPrefix + '/lots/doCreateLot',
submitEvent.currentTarget,
(responseJSON: {
success: boolean
errorMessage?: string
lotId?: number
}) => {
if (responseJSON.success) {
renderSelectedLotAndClose(responseJSON.lotId!, lotName)
} else {
bulmaJS.alert({
title: `Error Creating ${los.escapedAliases.Lot}`,
message: responseJSON.errorMessage ?? '',
contextualColorName: 'danger'
})
}
}
)
}
cityssm.openHtmlModal('lotOccupancy-selectLot', {
onshow: (modalElement) => {
los.populateAliases(modalElement)
},
onshown: (modalElement, closeModalFunction) => {
bulmaJS.toggleHtmlClipped()
lotSelectModalElement = modalElement
lotSelectCloseModalFunction = closeModalFunction
bulmaJS.init(modalElement)
// search Tab
const lotNameFilterElement = modalElement.querySelector(
'#lotSelect--lotName'
) as HTMLInputElement
if (
(document.querySelector('#lotOccupancy--lotId') as HTMLInputElement)
.value !== ''
) {
lotNameFilterElement.value = currentLotName
}
lotNameFilterElement.focus()
lotNameFilterElement.addEventListener('change', searchLots)
const occupancyStatusFilterElement = modalElement.querySelector(
'#lotSelect--occupancyStatus'
) as HTMLSelectElement
occupancyStatusFilterElement.addEventListener('change', searchLots)
if (currentLotName !== '') {
occupancyStatusFilterElement.value = ''
}
lotSelectFormElement = modalElement.querySelector(
'#form--lotSelect'
) as HTMLFormElement
lotSelectResultsElement = modalElement.querySelector(
'#resultsContainer--lotSelect'
) as HTMLElement
lotSelectFormElement.addEventListener('submit', (submitEvent) => {
submitEvent.preventDefault()
})
searchLots()
// Create Tab
if (exports.lotNamePattern) {
const regex = exports.lotNamePattern as RegExp
;(
modalElement.querySelector(
'#lotCreate--lotName'
) as HTMLInputElement
).pattern = regex.source
}
const lotTypeElement = modalElement.querySelector(
'#lotCreate--lotTypeId'
) as HTMLSelectElement
for (const lotType of exports.lotTypes as recordTypes.LotType[]) {
const optionElement = document.createElement('option')
optionElement.value = lotType.lotTypeId.toString()
optionElement.textContent = lotType.lotType
lotTypeElement.append(optionElement)
}
const lotStatusElement = modalElement.querySelector(
'#lotCreate--lotStatusId'
) as HTMLSelectElement
for (const lotStatus of exports.lotStatuses as recordTypes.LotStatus[]) {
const optionElement = document.createElement('option')
optionElement.value = lotStatus.lotStatusId.toString()
optionElement.textContent = lotStatus.lotStatus
lotStatusElement.append(optionElement)
}
const mapElement = modalElement.querySelector(
'#lotCreate--mapId'
) as HTMLSelectElement
for (const map of exports.maps as recordTypes.Map[]) {
const optionElement = document.createElement('option')
optionElement.value = map.mapId!.toString()
optionElement.textContent =
(map.mapName ?? '') === '' ? '(No Name)' : map.mapName!
mapElement.append(optionElement)
}
;(
modalElement.querySelector('#form--lotCreate') as HTMLFormElement
).addEventListener('submit', createLotAndSelect)
},
onremoved: () => {
bulmaJS.toggleHtmlClipped()
}
})
})
document
.querySelector('.is-lot-view-button')!
.addEventListener('click', () => {
const lotId = (
document.querySelector('#lotOccupancy--lotId') as HTMLInputElement
).value
if (lotId === '') {
bulmaJS.alert({
message: `No ${los.escapedAliases.lot} selected.`,
contextualColorName: 'info'
})
} else {
window.open(los.urlPrefix + '/lots/' + lotId)
}
})
document
.querySelector('.is-clear-lot-button')!
.addEventListener('click', () => {
if (lotNameElement.disabled) {
bulmaJS.alert({
message: 'You need to unlock the field before clearing it.',
contextualColorName: 'info'
})
} else {
lotNameElement.value = `(No ${los.escapedAliases.Lot})`
;(
document.querySelector('#lotOccupancy--lotId') as HTMLInputElement
).value = ''
los.setUnsavedChanges()
}
})
// Start Date
los.initializeDatePickers(formElement)
document
.querySelector('#lotOccupancy--occupancyStartDateString')!
.addEventListener('change', () => {
const endDatePicker = (
document.querySelector(
'#lotOccupancy--occupancyEndDateString'
) as HTMLInputElement
).bulmaCalendar.datePicker
endDatePicker.min = (
document.querySelector(
'#lotOccupancy--occupancyStartDateString'
) as HTMLInputElement
).value
endDatePicker.refresh()
})
los.initializeUnlockFieldButtons(formElement)
/*
* Occupants
*/
//=include lotOccupancyEditOccupants.js
if (!isCreate) {
//=include lotOccupancyEditComments.js
//=include lotOccupancyEditFees.js
}
})()