/* eslint-disable @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 containerElement = document.querySelector("#container--lotTypes") as HTMLElement; let lotTypes: recordTypes.LotType[] = exports.lotTypes; delete exports.lotTypes; const expandedLotTypes = new Set(); function 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"); } } function 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" }); } } function deleteLotType(clickEvent: Event) { const lotTypeId = Number.parseInt( ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotType" ) as HTMLElement ).dataset.lotTypeId!, 10 ); function doDelete() { cityssm.postJSON( los.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 } }); } function 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( los.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(); } }); } function 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( los.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(); } }); } function moveLotTypeUp(clickEvent: MouseEvent) { clickEvent.preventDefault(); const lotTypeId = ( (clickEvent.currentTarget as HTMLElement).closest(".container--lotType") as HTMLElement ).dataset.lotTypeId; cityssm.postJSON( los.urlPrefix + "/admin/doMoveLotTypeUp", { lotTypeId, moveToTop: clickEvent.shiftKey ? "1" : "0" }, lotTypeResponseHandler ); } function moveLotTypeDown(clickEvent: MouseEvent) { clickEvent.preventDefault(); const lotTypeId = ( (clickEvent.currentTarget as HTMLElement).closest(".container--lotType") as HTMLElement ).dataset.lotTypeId; cityssm.postJSON( los.urlPrefix + "/admin/doMoveLotTypeDown", { lotTypeId, moveToBottom: clickEvent.shiftKey ? "1" : "0" }, lotTypeResponseHandler ); } function 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; function updateMaximumLengthMin() { maximumLengthElement.min = minimumLengthElement.value; } function toggleInputFields() { if (lotTypeFieldValuesElement.value === "") { minimumLengthElement.disabled = false; maximumLengthElement.disabled = false; patternElement.disabled = false; } else { minimumLengthElement.disabled = true; maximumLengthElement.disabled = true; patternElement.disabled = true; } } function doUpdate(submitEvent: SubmitEvent) { submitEvent.preventDefault(); cityssm.postJSON( los.urlPrefix + "/admin/doUpdateLotTypeField", submitEvent.currentTarget, (responseJSON: { success: boolean; errorMessage?: string; occupancyTypes?: recordTypes.OccupancyType[]; }) => { lotTypeResponseHandler(responseJSON); if (responseJSON.success) { editCloseModalFunction(); } } ); } function doDelete() { cityssm.postJSON( los.urlPrefix + "/admin/doDeleteLotTypeField", { lotTypeFieldId }, (responseJSON: { success: boolean; errorMessage?: string; lotTypes?: recordTypes.LotType[]; }) => { lotTypeResponseHandler(responseJSON); if (responseJSON.success) { editCloseModalFunction(); } } ); } function confirmDoDelete() { 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" ) as HTMLInputElement; minimumLengthElement.value = lotTypeField.minimumLength!.toString(); maximumLengthElement = modalElement.querySelector( "#lotTypeFieldEdit--maximumLength" ) as HTMLInputElement; maximumLengthElement.value = lotTypeField.maximumLength!.toString(); patternElement = modalElement.querySelector( "#lotTypeFieldEdit--pattern" ) as HTMLInputElement; patternElement.value = lotTypeField.pattern!; lotTypeFieldValuesElement = modalElement.querySelector( "#lotTypeFieldEdit--lotTypeFieldValues" ) as HTMLTextAreaElement; 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", confirmDoDelete); }, onremoved() { bulmaJS.toggleHtmlClipped(); cityssm.disableNavBlocker(); } }); } function 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); } function moveLotTypeFieldUp(clickEvent: MouseEvent) { clickEvent.preventDefault(); const lotTypeFieldId = ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotTypeField" ) as HTMLElement ).dataset.lotTypeFieldId; cityssm.postJSON( los.urlPrefix + "/admin/doMoveLotTypeFieldUp", { lotTypeFieldId, moveToTop: clickEvent.shiftKey ? "1" : "0" }, lotTypeResponseHandler ); } function moveLotTypeFieldDown(clickEvent: MouseEvent) { clickEvent.preventDefault(); const lotTypeFieldId = ( (clickEvent.currentTarget as HTMLElement).closest( ".container--lotTypeField" ) as HTMLElement ).dataset.lotTypeFieldId; cityssm.postJSON( los.urlPrefix + "/admin/doMoveLotTypeFieldDown", { lotTypeFieldId, moveToBottom: clickEvent.shiftKey ? "1" : "0" }, lotTypeResponseHandler ); } function 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 = '
' + '" + '
' + ('
' + los.getMoveUpDownButtonFieldHTML( "button--moveLotTypeFieldUp", "button--moveLotTypeFieldDown" ) + "
") + "
" + "
"; panelBlockElement .querySelector(".button--editLotTypeField")! .addEventListener("click", openEditLotTypeFieldByClick); ( panelBlockElement.querySelector( ".button--moveLotTypeFieldUp" ) as HTMLButtonElement ).addEventListener("click", moveLotTypeFieldUp); ( panelBlockElement.querySelector( ".button--moveLotTypeFieldDown" ) as HTMLButtonElement ).addEventListener("click", moveLotTypeFieldDown); panelElement.append(panelBlockElement); } } } function 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) + "

" + "
" + "
") + ('
' + ('
' + '" + "
") + ('
' + '" + "
") + ('
' + '" + "
") + ('
' + los.getMoveUpDownButtonFieldHTML( "button--moveLotTypeUp", "button--moveLotTypeDown" ) + "
") + "
") + "
" + "
"; 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") as HTMLButtonElement ).addEventListener("click", moveLotTypeUp); ( lotTypeContainer.querySelector(".button--moveLotTypeDown") as HTMLButtonElement ).addEventListener("click", moveLotTypeDown); containerElement.append(lotTypeContainer); } } (document.querySelector("#button--addLotType") as HTMLButtonElement).addEventListener( "click", () => { let addCloseModalFunction: () => void; const doAdd = (submitEvent: SubmitEvent) => { submitEvent.preventDefault(); cityssm.postJSON( los.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(); })();