/* eslint-disable 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 urlPrefix = document.querySelector("main").dataset.urlPrefix; const containerElement = document.querySelector("#container--lotTypes") as HTMLElement; let lotTypes: recordTypes.LotType[] = exports.lotTypes; delete exports.lotTypes; const expandedLotTypes = new Set(); const toggleLotTypeFields = (clickEvent: Event) => { const toggleButtonElement = clickEvent.currentTarget as HTMLButtonElement; const lotTypeElement = toggleButtonElement.closest(".container--lotType") as HTMLElement; const lotTypeId = Number.parseInt(lotTypeElement.dataset.lotTypeId, 10); if (expandedLotTypes.has(lotTypeId)) { expandedLotTypes.delete(lotTypeId); } else { expandedLotTypes.add(lotTypeId); } toggleButtonElement.innerHTML = expandedLotTypes.has(lotTypeId) ? '' : ''; const panelBlockElements = lotTypeElement.querySelectorAll(".panel-block"); for (const panelBlockElement of panelBlockElements) { panelBlockElement.classList.toggle("is-hidden"); } }; const lotTypeResponseHandler = (responseJSON: { success: boolean; errorMessage?: string; lotTypes?: recordTypes.LotType[]; }) => { if (responseJSON.success) { lotTypes = responseJSON.lotTypes; renderLotTypes(); } else { bulmaJS.alert({ title: "Error Updating " + exports.aliases.lot + " Type", message: responseJSON.errorMessage, contextualColorName: "danger" }); } }; const deleteLotType = (clickEvent: Event) => { const lotTypeId = Number.parseInt( ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotType" ) as HTMLElement ).dataset.lotTypeId, 10 ); const doDelete = () => { cityssm.postJSON( urlPrefix + "/admin/doDeleteLotType", { lotTypeId }, lotTypeResponseHandler ); }; bulmaJS.confirm({ title: "Delete " + exports.aliases.lot + " Type", message: "Are you sure you want to delete this " + exports.aliases.lot.toLowerCase() + " type?", contextualColorName: "warning", okButton: { text: "Yes, Delete " + exports.aliases.lot + " Type", callbackFunction: doDelete } }); }; const openEditLotType = (clickEvent: Event) => { const lotTypeId = Number.parseInt( ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotType" ) as HTMLElement ).dataset.lotTypeId, 10 ); const lotType = lotTypes.find((currentLotType) => { return lotTypeId === currentLotType.lotTypeId; }); let editCloseModalFunction: () => void; const doEdit = (submitEvent: SubmitEvent) => { submitEvent.preventDefault(); cityssm.postJSON( urlPrefix + "/admin/doUpdateLotType", submitEvent.currentTarget, (responseJSON: { success: boolean; errorMessage?: string; occupancyTypes?: recordTypes.OccupancyType[]; }) => { lotTypeResponseHandler(responseJSON); if (responseJSON.success) { editCloseModalFunction(); } } ); }; cityssm.openHtmlModal("adminLotTypes-editLotType", { onshow: (modalElement) => { los.populateAliases(modalElement); (modalElement.querySelector("#lotTypeEdit--lotTypeId") as HTMLInputElement).value = lotTypeId.toString(); (modalElement.querySelector("#lotTypeEdit--lotType") as HTMLInputElement).value = lotType.lotType; }, onshown: (modalElement, closeModalFunction) => { editCloseModalFunction = closeModalFunction; (modalElement.querySelector("#lotTypeEdit--lotType") as HTMLInputElement).focus(); modalElement.querySelector("form").addEventListener("submit", doEdit); bulmaJS.toggleHtmlClipped(); }, onremoved: () => { bulmaJS.toggleHtmlClipped(); } }); }; const openAddLotTypeField = (clickEvent: Event) => { const lotTypeId = Number.parseInt( ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotType" ) as HTMLElement ).dataset.lotTypeId, 10 ); let addCloseModalFunction: () => void; const doAdd = (submitEvent: SubmitEvent) => { submitEvent.preventDefault(); cityssm.postJSON( urlPrefix + "/admin/doAddLotTypeField", submitEvent.currentTarget, (responseJSON: { success: boolean; errorMessage?: string; lotTypes?: recordTypes.LotType[]; lotTypeFieldId?: number; }) => { expandedLotTypes.add(lotTypeId); lotTypeResponseHandler(responseJSON); if (responseJSON.success) { addCloseModalFunction(); openEditLotTypeField(lotTypeId, responseJSON.lotTypeFieldId); } } ); }; cityssm.openHtmlModal("adminLotTypes-addLotTypeField", { onshow: (modalElement) => { los.populateAliases(modalElement); if (lotTypeId) { ( modalElement.querySelector( "#lotTypeFieldAdd--lotTypeId" ) as HTMLInputElement ).value = lotTypeId.toString(); } }, onshown: (modalElement, closeModalFunction) => { addCloseModalFunction = closeModalFunction; ( modalElement.querySelector("#lotTypeFieldAdd--lotTypeField") as HTMLInputElement ).focus(); modalElement.querySelector("form").addEventListener("submit", doAdd); bulmaJS.toggleHtmlClipped(); }, onremoved: () => { bulmaJS.toggleHtmlClipped(); } }); }; const moveLotTypeUp = (clickEvent: Event) => { clickEvent.preventDefault(); const lotTypeId = ( (clickEvent.currentTarget as HTMLElement).closest(".container--lotType") as HTMLElement ).dataset.lotTypeId; cityssm.postJSON( urlPrefix + "/admin/doMoveLotTypeUp", { lotTypeId }, lotTypeResponseHandler ); }; const moveLotTypeDown = (clickEvent: Event) => { clickEvent.preventDefault(); const lotTypeId = ( (clickEvent.currentTarget as HTMLElement).closest(".container--lotType") as HTMLElement ).dataset.lotTypeId; cityssm.postJSON( urlPrefix + "/admin/doMoveLotTypeDown", { lotTypeId }, lotTypeResponseHandler ); }; const openEditLotTypeField = (lotTypeId: number, lotTypeFieldId: number) => { const lotType = lotTypes.find((currentLotType) => { return currentLotType.lotTypeId === lotTypeId; }); const lotTypeField = lotType.lotTypeFields.find((currentLotTypeField) => { return currentLotTypeField.lotTypeFieldId === lotTypeFieldId; }); let minimumLengthElement: HTMLInputElement; let maximumLengthElement: HTMLInputElement; let patternElement: HTMLInputElement; let lotTypeFieldValuesElement: HTMLTextAreaElement; let editCloseModalFunction: () => void; const updateMaximumLengthMin = () => { maximumLengthElement.min = minimumLengthElement.value; }; const toggleInputFields = () => { if (lotTypeFieldValuesElement.value === "") { minimumLengthElement.disabled = false; maximumLengthElement.disabled = false; patternElement.disabled = false; } else { minimumLengthElement.disabled = true; maximumLengthElement.disabled = true; patternElement.disabled = true; } }; const doUpdate = (submitEvent: SubmitEvent) => { submitEvent.preventDefault(); cityssm.postJSON( urlPrefix + "/admin/doUpdateLotTypeField", submitEvent.currentTarget, (responseJSON: { success: boolean; errorMessage?: string; occupancyTypes?: recordTypes.OccupancyType[]; }) => { lotTypeResponseHandler(responseJSON); if (responseJSON.success) { editCloseModalFunction(); } } ); }; const doDelete = () => { const _doDelete = () => { cityssm.postJSON( urlPrefix + "/admin/doDeleteLotTypeField", { lotTypeFieldId }, (responseJSON: { success: boolean; errorMessage?: string; lotTypes?: recordTypes.LotType[]; }) => { lotTypeResponseHandler(responseJSON); if (responseJSON.success) { editCloseModalFunction(); } } ); }; bulmaJS.confirm({ title: "Delete Field", message: "Are you sure you want to delete this field? Note that historical records that make use of this field will not be affected.", contextualColorName: "warning", okButton: { text: "Yes, Delete Field", callbackFunction: _doDelete } }); }; cityssm.openHtmlModal("adminLotTypes-editLotTypeField", { onshow: (modalElement) => { los.populateAliases(modalElement); ( modalElement.querySelector( "#lotTypeFieldEdit--lotTypeFieldId" ) as HTMLInputElement ).value = lotTypeField.lotTypeFieldId.toString(); ( modalElement.querySelector( "#lotTypeFieldEdit--lotTypeField" ) as HTMLInputElement ).value = lotTypeField.lotTypeField; ( modalElement.querySelector("#lotTypeFieldEdit--isRequired") as HTMLSelectElement ).value = lotTypeField.isRequired ? "1" : "0"; minimumLengthElement = modalElement.querySelector( "#lotTypeFieldEdit--minimumLength" ); minimumLengthElement.value = lotTypeField.minimumLength.toString(); maximumLengthElement = modalElement.querySelector( "#lotTypeFieldEdit--maximumLength" ); maximumLengthElement.value = lotTypeField.maximumLength.toString(); patternElement = modalElement.querySelector("#lotTypeFieldEdit--pattern"); patternElement.value = lotTypeField.pattern; lotTypeFieldValuesElement = modalElement.querySelector( "#lotTypeFieldEdit--lotTypeFieldValues" ); lotTypeFieldValuesElement.value = lotTypeField.lotTypeFieldValues; toggleInputFields(); }, onshown: (modalElement, closeModalFunction) => { editCloseModalFunction = closeModalFunction; bulmaJS.init(modalElement); bulmaJS.toggleHtmlClipped(); cityssm.enableNavBlocker(); modalElement.querySelector("form").addEventListener("submit", doUpdate); minimumLengthElement.addEventListener("keyup", updateMaximumLengthMin); updateMaximumLengthMin(); lotTypeFieldValuesElement.addEventListener("keyup", toggleInputFields); modalElement .querySelector("#button--deleteLotTypeField") .addEventListener("click", doDelete); }, onremoved: () => { bulmaJS.toggleHtmlClipped(); cityssm.disableNavBlocker(); } }); }; const openEditLotTypeFieldByClick = (clickEvent: Event) => { clickEvent.preventDefault(); const lotTypeFieldId = Number.parseInt( ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotTypeField" ) as HTMLElement ).dataset.lotTypeFieldId, 10 ); const lotTypeId = Number.parseInt( ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotType" ) as HTMLElement ).dataset.lotTypeId, 10 ); openEditLotTypeField(lotTypeId, lotTypeFieldId); }; const moveLotTypeFieldUp = (clickEvent: Event) => { clickEvent.preventDefault(); const lotTypeFieldId = ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotTypeField" ) as HTMLElement ).dataset.lotTypeFieldId; cityssm.postJSON( urlPrefix + "/admin/doMoveLotTypeFieldUp", { lotTypeFieldId }, lotTypeResponseHandler ); }; const moveLotTypeFieldDown = (clickEvent: Event) => { clickEvent.preventDefault(); const lotTypeFieldId = ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotTypeField" ) as HTMLElement ).dataset.lotTypeFieldId; cityssm.postJSON( urlPrefix + "/admin/doMoveLotTypeFieldDown", { lotTypeFieldId }, lotTypeResponseHandler ); }; const renderLotTypeFields = ( panelElement: HTMLElement, lotTypeId: number, lotTypeFields: recordTypes.LotTypeField[] ) => { if (lotTypeFields.length === 0) { panelElement.insertAdjacentHTML( "beforeend", '
' + '
' + '

There are no additional fields.

' + "
" + "
" ); } else { for (const lotTypeField of lotTypeFields) { const panelBlockElement = document.createElement("div"); panelBlockElement.className = "panel-block is-block container--lotTypeField"; if (!expandedLotTypes.has(lotTypeId)) { panelBlockElement.classList.add("is-hidden"); } panelBlockElement.dataset.lotTypeFieldId = lotTypeField.lotTypeFieldId.toString(); panelBlockElement.innerHTML = '
' + '" + '
' + ('
' + '
' + '
' + '" + "
" + '
' + '" + "
" + "
" + "
") + "
" + "
"; panelBlockElement .querySelector(".button--editLotTypeField") .addEventListener("click", openEditLotTypeFieldByClick); panelBlockElement .querySelector(".button--moveLotTypeFieldUp") .addEventListener("click", moveLotTypeFieldUp); panelBlockElement .querySelector(".button--moveLotTypeFieldDown") .addEventListener("click", moveLotTypeFieldDown); panelElement.append(panelBlockElement); } } }; const renderLotTypes = () => { containerElement.innerHTML = ""; if (lotTypes.length === 0) { containerElement.insertAdjacentHTML( "afterbegin", '
There are no active ' + exports.aliases.lot.toLowerCase() + " types.

" + "
" ); return; } for (const lotType of lotTypes) { const lotTypeContainer = document.createElement("div"); lotTypeContainer.className = "panel container--lotType"; lotTypeContainer.dataset.lotTypeId = lotType.lotTypeId.toString(); lotTypeContainer.innerHTML = '
' + '
' + ('
' + '
' + '" + "
" + '
' + '

' + cityssm.escapeHTML(lotType.lotType) + "

" + "
" + "
") + ('
' + ('
' + '" + "
") + ('
' + '" + "
") + ('
' + '" + "
") + ('
' + '
' + '
' + '" + "
" + '
' + '" + "
" + "
" + "
") + "
") + "
" + "
"; renderLotTypeFields(lotTypeContainer, lotType.lotTypeId, lotType.lotTypeFields); lotTypeContainer .querySelector(".button--toggleLotTypeFields") .addEventListener("click", toggleLotTypeFields); lotTypeContainer .querySelector(".button--deleteLotType") .addEventListener("click", deleteLotType); lotTypeContainer .querySelector(".button--editLotType") .addEventListener("click", openEditLotType); lotTypeContainer .querySelector(".button--addLotTypeField") .addEventListener("click", openAddLotTypeField); lotTypeContainer .querySelector(".button--moveLotTypeUp") .addEventListener("click", moveLotTypeUp); lotTypeContainer .querySelector(".button--moveLotTypeDown") .addEventListener("click", moveLotTypeDown); containerElement.append(lotTypeContainer); } }; document.querySelector("#button--addLotType").addEventListener("click", () => { let addCloseModalFunction: () => void; const doAdd = (submitEvent: SubmitEvent) => { submitEvent.preventDefault(); cityssm.postJSON( urlPrefix + "/admin/doAddLotType", submitEvent.currentTarget, (responseJSON: { success: boolean; errorMessage?: string; lotTypes?: recordTypes.LotType[]; }) => { if (responseJSON.success) { addCloseModalFunction(); lotTypes = responseJSON.lotTypes; renderLotTypes(); } else { bulmaJS.alert({ title: "Error Adding " + exports.aliases.lot + " Type", message: responseJSON.errorMessage, contextualColorName: "danger" }); } } ); }; cityssm.openHtmlModal("adminLotTypes-addLotType", { onshow: (modalElement) => { los.populateAliases(modalElement); }, onshown: (modalElement, closeModalFunction) => { addCloseModalFunction = closeModalFunction; (modalElement.querySelector("#lotTypeAdd--lotType") as HTMLInputElement).focus(); modalElement.querySelector("form").addEventListener("submit", doAdd); bulmaJS.toggleHtmlClipped(); }, onremoved: () => { bulmaJS.toggleHtmlClipped(); } }); }); renderLotTypes(); })();