From f7d91e5d09428b009f8b7769ca198967cfb021c8 Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Fri, 26 Aug 2022 11:10:07 -0400 Subject: [PATCH] lot occupant type maintenance --- handlers/admin-post/doAddLotOccupantType.d.ts | 3 + handlers/admin-post/doAddLotOccupantType.js | 12 + handlers/admin-post/doAddLotOccupantType.ts | 28 ++ .../admin-post/doDeleteLotOccupantType.d.ts | 3 + .../admin-post/doDeleteLotOccupantType.js | 11 + .../admin-post/doDeleteLotOccupantType.ts | 27 ++ .../admin-post/doMoveLotOccupantTypeDown.d.ts | 3 + .../admin-post/doMoveLotOccupantTypeDown.js | 11 + .../admin-post/doMoveLotOccupantTypeDown.ts | 27 ++ .../admin-post/doMoveLotOccupantTypeUp.d.ts | 3 + .../admin-post/doMoveLotOccupantTypeUp.js | 11 + .../admin-post/doMoveLotOccupantTypeUp.ts | 27 ++ .../admin-post/doUpdateLotOccupantType.d.ts | 3 + .../admin-post/doUpdateLotOccupantType.js | 11 + .../admin-post/doUpdateLotOccupantType.ts | 27 ++ helpers/lotOccupancyDB/addLotOccupantType.js | 2 +- helpers/lotOccupancyDB/addLotOccupantType.ts | 2 +- .../lotOccupancyDB/deleteLotOccupantType.d.ts | 3 + .../lotOccupancyDB/deleteLotOccupantType.js | 17 + .../lotOccupancyDB/deleteLotOccupantType.ts | 39 ++ helpers/lotOccupancyDB/getLotOccupantTypes.js | 15 +- helpers/lotOccupancyDB/getLotOccupantTypes.ts | 22 +- .../moveLotOccupantTypeDown.d.ts | 2 + .../lotOccupancyDB/moveLotOccupantTypeDown.js | 26 ++ .../lotOccupancyDB/moveLotOccupantTypeDown.ts | 44 ++ .../lotOccupancyDB/moveLotOccupantTypeUp.d.ts | 2 + .../lotOccupancyDB/moveLotOccupantTypeUp.js | 30 ++ .../lotOccupancyDB/moveLotOccupantTypeUp.ts | 49 +++ .../lotOccupancyDB/updateLotOccupantType.d.ts | 7 + .../lotOccupancyDB/updateLotOccupantType.js | 19 + .../lotOccupancyDB/updateLotOccupantType.ts | 47 ++ public-typescript/adminTables.js | 177 ++++++++ public-typescript/adminTables.ts | 405 ++++++++++++++---- public/javascripts/adminTables.min.js | 2 +- routes/admin.js | 12 +- routes/admin.ts | 31 +- views/admin-tables.ejs | 27 ++ 37 files changed, 1099 insertions(+), 88 deletions(-) create mode 100644 handlers/admin-post/doAddLotOccupantType.d.ts create mode 100644 handlers/admin-post/doAddLotOccupantType.js create mode 100644 handlers/admin-post/doAddLotOccupantType.ts create mode 100644 handlers/admin-post/doDeleteLotOccupantType.d.ts create mode 100644 handlers/admin-post/doDeleteLotOccupantType.js create mode 100644 handlers/admin-post/doDeleteLotOccupantType.ts create mode 100644 handlers/admin-post/doMoveLotOccupantTypeDown.d.ts create mode 100644 handlers/admin-post/doMoveLotOccupantTypeDown.js create mode 100644 handlers/admin-post/doMoveLotOccupantTypeDown.ts create mode 100644 handlers/admin-post/doMoveLotOccupantTypeUp.d.ts create mode 100644 handlers/admin-post/doMoveLotOccupantTypeUp.js create mode 100644 handlers/admin-post/doMoveLotOccupantTypeUp.ts create mode 100644 handlers/admin-post/doUpdateLotOccupantType.d.ts create mode 100644 handlers/admin-post/doUpdateLotOccupantType.js create mode 100644 handlers/admin-post/doUpdateLotOccupantType.ts create mode 100644 helpers/lotOccupancyDB/deleteLotOccupantType.d.ts create mode 100644 helpers/lotOccupancyDB/deleteLotOccupantType.js create mode 100644 helpers/lotOccupancyDB/deleteLotOccupantType.ts create mode 100644 helpers/lotOccupancyDB/moveLotOccupantTypeDown.d.ts create mode 100644 helpers/lotOccupancyDB/moveLotOccupantTypeDown.js create mode 100644 helpers/lotOccupancyDB/moveLotOccupantTypeDown.ts create mode 100644 helpers/lotOccupancyDB/moveLotOccupantTypeUp.d.ts create mode 100644 helpers/lotOccupancyDB/moveLotOccupantTypeUp.js create mode 100644 helpers/lotOccupancyDB/moveLotOccupantTypeUp.ts create mode 100644 helpers/lotOccupancyDB/updateLotOccupantType.d.ts create mode 100644 helpers/lotOccupancyDB/updateLotOccupantType.js create mode 100644 helpers/lotOccupancyDB/updateLotOccupantType.ts diff --git a/handlers/admin-post/doAddLotOccupantType.d.ts b/handlers/admin-post/doAddLotOccupantType.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/admin-post/doAddLotOccupantType.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/admin-post/doAddLotOccupantType.js b/handlers/admin-post/doAddLotOccupantType.js new file mode 100644 index 00000000..b1513222 --- /dev/null +++ b/handlers/admin-post/doAddLotOccupantType.js @@ -0,0 +1,12 @@ +import { addLotOccupantType } from "../../helpers/lotOccupancyDB/addLotOccupantType.js"; +import { getLotOccupantTypes } from "../../helpers/functions.cache.js"; +export const handler = async (request, response) => { + const lotOccupantTypeId = addLotOccupantType(request.body, request.session); + const lotOccupantTypes = getLotOccupantTypes(); + response.json({ + success: true, + lotOccupantTypeId, + lotOccupantTypes + }); +}; +export default handler; diff --git a/handlers/admin-post/doAddLotOccupantType.ts b/handlers/admin-post/doAddLotOccupantType.ts new file mode 100644 index 00000000..b13b68f7 --- /dev/null +++ b/handlers/admin-post/doAddLotOccupantType.ts @@ -0,0 +1,28 @@ +import type { + RequestHandler +} from "express"; + +import { + addLotOccupantType +} from "../../helpers/lotOccupancyDB/addLotOccupantType.js"; + +import { + getLotOccupantTypes +} from "../../helpers/functions.cache.js"; + + +export const handler: RequestHandler = async (request, response) => { + + const lotOccupantTypeId = addLotOccupantType(request.body, request.session); + + const lotOccupantTypes = getLotOccupantTypes(); + + response.json({ + success: true, + lotOccupantTypeId, + lotOccupantTypes + }); +}; + + +export default handler; \ No newline at end of file diff --git a/handlers/admin-post/doDeleteLotOccupantType.d.ts b/handlers/admin-post/doDeleteLotOccupantType.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/admin-post/doDeleteLotOccupantType.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/admin-post/doDeleteLotOccupantType.js b/handlers/admin-post/doDeleteLotOccupantType.js new file mode 100644 index 00000000..49d92746 --- /dev/null +++ b/handlers/admin-post/doDeleteLotOccupantType.js @@ -0,0 +1,11 @@ +import { deleteLotOccupantType } from "../../helpers/lotOccupancyDB/deleteLotOccupantType.js"; +import { getLotOccupantTypes } from "../../helpers/functions.cache.js"; +export const handler = async (request, response) => { + const success = deleteLotOccupantType(request.body.lotOccupantTypeId, request.session); + const lotOccupantTypes = getLotOccupantTypes(); + response.json({ + success, + lotOccupantTypes + }); +}; +export default handler; diff --git a/handlers/admin-post/doDeleteLotOccupantType.ts b/handlers/admin-post/doDeleteLotOccupantType.ts new file mode 100644 index 00000000..7df6b0ad --- /dev/null +++ b/handlers/admin-post/doDeleteLotOccupantType.ts @@ -0,0 +1,27 @@ +import type { + RequestHandler +} from "express"; + +import { + deleteLotOccupantType +} from "../../helpers/lotOccupancyDB/deleteLotOccupantType.js"; + +import { + getLotOccupantTypes +} from "../../helpers/functions.cache.js"; + + +export const handler: RequestHandler = async (request, response) => { + + const success = deleteLotOccupantType(request.body.lotOccupantTypeId, request.session); + + const lotOccupantTypes = getLotOccupantTypes(); + + response.json({ + success, + lotOccupantTypes + }); +}; + + +export default handler; \ No newline at end of file diff --git a/handlers/admin-post/doMoveLotOccupantTypeDown.d.ts b/handlers/admin-post/doMoveLotOccupantTypeDown.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/admin-post/doMoveLotOccupantTypeDown.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/admin-post/doMoveLotOccupantTypeDown.js b/handlers/admin-post/doMoveLotOccupantTypeDown.js new file mode 100644 index 00000000..57f0b58c --- /dev/null +++ b/handlers/admin-post/doMoveLotOccupantTypeDown.js @@ -0,0 +1,11 @@ +import { moveLotOccupantTypeDown } from "../../helpers/lotOccupancyDB/moveLotOccupantTypeDown.js"; +import { getLotOccupantTypes } from "../../helpers/functions.cache.js"; +export const handler = async (request, response) => { + const success = moveLotOccupantTypeDown(request.body.lotOccupantTypeId); + const lotOccupantTypes = getLotOccupantTypes(); + response.json({ + success, + lotOccupantTypes + }); +}; +export default handler; diff --git a/handlers/admin-post/doMoveLotOccupantTypeDown.ts b/handlers/admin-post/doMoveLotOccupantTypeDown.ts new file mode 100644 index 00000000..a2709d40 --- /dev/null +++ b/handlers/admin-post/doMoveLotOccupantTypeDown.ts @@ -0,0 +1,27 @@ +import type { + RequestHandler +} from "express"; + +import { + moveLotOccupantTypeDown +} from "../../helpers/lotOccupancyDB/moveLotOccupantTypeDown.js"; + +import { + getLotOccupantTypes +} from "../../helpers/functions.cache.js"; + + +export const handler: RequestHandler = async (request, response) => { + + const success = moveLotOccupantTypeDown(request.body.lotOccupantTypeId); + + const lotOccupantTypes = getLotOccupantTypes(); + + response.json({ + success, + lotOccupantTypes + }); +}; + + +export default handler; \ No newline at end of file diff --git a/handlers/admin-post/doMoveLotOccupantTypeUp.d.ts b/handlers/admin-post/doMoveLotOccupantTypeUp.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/admin-post/doMoveLotOccupantTypeUp.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/admin-post/doMoveLotOccupantTypeUp.js b/handlers/admin-post/doMoveLotOccupantTypeUp.js new file mode 100644 index 00000000..5e2e0d51 --- /dev/null +++ b/handlers/admin-post/doMoveLotOccupantTypeUp.js @@ -0,0 +1,11 @@ +import { moveLotOccupantTypeUp } from "../../helpers/lotOccupancyDB/moveLotOccupantTypeUp.js"; +import { getLotOccupantTypes } from "../../helpers/functions.cache.js"; +export const handler = async (request, response) => { + const success = moveLotOccupantTypeUp(request.body.lotOccupantTypeId); + const lotOccupantTypes = getLotOccupantTypes(); + response.json({ + success, + lotOccupantTypes + }); +}; +export default handler; diff --git a/handlers/admin-post/doMoveLotOccupantTypeUp.ts b/handlers/admin-post/doMoveLotOccupantTypeUp.ts new file mode 100644 index 00000000..63cc2a6e --- /dev/null +++ b/handlers/admin-post/doMoveLotOccupantTypeUp.ts @@ -0,0 +1,27 @@ +import type { + RequestHandler +} from "express"; + +import { + moveLotOccupantTypeUp +} from "../../helpers/lotOccupancyDB/moveLotOccupantTypeUp.js"; + +import { + getLotOccupantTypes +} from "../../helpers/functions.cache.js"; + + +export const handler: RequestHandler = async (request, response) => { + + const success = moveLotOccupantTypeUp(request.body.lotOccupantTypeId); + + const lotOccupantTypes = getLotOccupantTypes(); + + response.json({ + success, + lotOccupantTypes + }); +}; + + +export default handler; \ No newline at end of file diff --git a/handlers/admin-post/doUpdateLotOccupantType.d.ts b/handlers/admin-post/doUpdateLotOccupantType.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/admin-post/doUpdateLotOccupantType.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/admin-post/doUpdateLotOccupantType.js b/handlers/admin-post/doUpdateLotOccupantType.js new file mode 100644 index 00000000..82d3d080 --- /dev/null +++ b/handlers/admin-post/doUpdateLotOccupantType.js @@ -0,0 +1,11 @@ +import { updateLotOccupantType } from "../../helpers/lotOccupancyDB/updateLotOccupantType.js"; +import { getLotOccupantTypes } from "../../helpers/functions.cache.js"; +export const handler = async (request, response) => { + const success = updateLotOccupantType(request.body, request.session); + const lotOccupantTypes = getLotOccupantTypes(); + response.json({ + success, + lotOccupantTypes + }); +}; +export default handler; diff --git a/handlers/admin-post/doUpdateLotOccupantType.ts b/handlers/admin-post/doUpdateLotOccupantType.ts new file mode 100644 index 00000000..b103cc20 --- /dev/null +++ b/handlers/admin-post/doUpdateLotOccupantType.ts @@ -0,0 +1,27 @@ +import type { + RequestHandler +} from "express"; + +import { + updateLotOccupantType +} from "../../helpers/lotOccupancyDB/updateLotOccupantType.js"; + +import { + getLotOccupantTypes +} from "../../helpers/functions.cache.js"; + + +export const handler: RequestHandler = async (request, response) => { + + const success = updateLotOccupantType(request.body, request.session); + + const lotOccupantTypes = getLotOccupantTypes(); + + response.json({ + success, + lotOccupantTypes + }); +}; + + +export default handler; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/addLotOccupantType.js b/helpers/lotOccupancyDB/addLotOccupantType.js index 20340200..10663923 100644 --- a/helpers/lotOccupancyDB/addLotOccupantType.js +++ b/helpers/lotOccupancyDB/addLotOccupantType.js @@ -10,7 +10,7 @@ export const addLotOccupantType = (lotOccupantTypeForm, requestSession) => { " recordCreate_userName, recordCreate_timeMillis," + " recordUpdate_userName, recordUpdate_timeMillis)" + " values (?, ?, ?, ?, ?, ?)") - .run(lotOccupantTypeForm.lotOccupantType, (lotOccupantTypeForm.orderNumber || 0), requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis); + .run(lotOccupantTypeForm.lotOccupantType, (lotOccupantTypeForm.orderNumber || -1), requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis); database.close(); clearLotOccupantTypesCache(); return result.lastInsertRowid; diff --git a/helpers/lotOccupancyDB/addLotOccupantType.ts b/helpers/lotOccupancyDB/addLotOccupantType.ts index 28d04c27..24aae01d 100644 --- a/helpers/lotOccupancyDB/addLotOccupantType.ts +++ b/helpers/lotOccupancyDB/addLotOccupantType.ts @@ -28,7 +28,7 @@ export const addLotOccupantType = " recordUpdate_userName, recordUpdate_timeMillis)" + " values (?, ?, ?, ?, ?, ?)") .run(lotOccupantTypeForm.lotOccupantType, - (lotOccupantTypeForm.orderNumber || 0), + (lotOccupantTypeForm.orderNumber || -1), requestSession.user.userName, rightNowMillis, requestSession.user.userName, diff --git a/helpers/lotOccupancyDB/deleteLotOccupantType.d.ts b/helpers/lotOccupancyDB/deleteLotOccupantType.d.ts new file mode 100644 index 00000000..4e095f08 --- /dev/null +++ b/helpers/lotOccupancyDB/deleteLotOccupantType.d.ts @@ -0,0 +1,3 @@ +import type * as recordTypes from "../../types/recordTypes"; +export declare const deleteLotOccupantType: (lotOccupantTypeId: number | string, requestSession: recordTypes.PartialSession) => boolean; +export default deleteLotOccupantType; diff --git a/helpers/lotOccupancyDB/deleteLotOccupantType.js b/helpers/lotOccupancyDB/deleteLotOccupantType.js new file mode 100644 index 00000000..0384e7bb --- /dev/null +++ b/helpers/lotOccupancyDB/deleteLotOccupantType.js @@ -0,0 +1,17 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { clearLotOccupantTypesCache } from "../functions.cache.js"; +export const deleteLotOccupantType = (lotOccupantTypeId, requestSession) => { + const database = sqlite(databasePath); + const rightNowMillis = Date.now(); + const result = database + .prepare("update LotOccupantTypes" + + " set recordDelete_userName = ?," + + " recordDelete_timeMillis = ?" + + " where lotOccupantTypeId = ?") + .run(requestSession.user.userName, rightNowMillis, lotOccupantTypeId); + database.close(); + clearLotOccupantTypesCache(); + return (result.changes > 0); +}; +export default deleteLotOccupantType; diff --git a/helpers/lotOccupancyDB/deleteLotOccupantType.ts b/helpers/lotOccupancyDB/deleteLotOccupantType.ts new file mode 100644 index 00000000..22edad65 --- /dev/null +++ b/helpers/lotOccupancyDB/deleteLotOccupantType.ts @@ -0,0 +1,39 @@ +import sqlite from "better-sqlite3"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; + +import { + clearLotOccupantTypesCache +} from "../functions.cache.js"; + +import type * as recordTypes from "../../types/recordTypes"; + + +export const deleteLotOccupantType = + (lotOccupantTypeId: number | string, + requestSession: recordTypes.PartialSession): boolean => { + + const database = sqlite(databasePath); + + const rightNowMillis = Date.now(); + + const result = database + .prepare("update LotOccupantTypes" + + " set recordDelete_userName = ?," + + " recordDelete_timeMillis = ?" + + " where lotOccupantTypeId = ?") + .run(requestSession.user.userName, + rightNowMillis, + lotOccupantTypeId); + + database.close(); + + clearLotOccupantTypesCache(); + + return (result.changes > 0); + }; + + +export default deleteLotOccupantType; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/getLotOccupantTypes.js b/helpers/lotOccupancyDB/getLotOccupantTypes.js index 0160296d..0989e69d 100644 --- a/helpers/lotOccupancyDB/getLotOccupantTypes.js +++ b/helpers/lotOccupancyDB/getLotOccupantTypes.js @@ -1,15 +1,24 @@ import sqlite from "better-sqlite3"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; export const getLotOccupantTypes = () => { - const database = sqlite(databasePath, { - readonly: true - }); + const database = sqlite(databasePath); const lotOccupantTypes = database .prepare("select lotOccupantTypeId, lotOccupantType" + " from LotOccupantTypes" + " where recordDelete_timeMillis is null" + " order by orderNumber, lotOccupantType") .all(); + let expectedOrderNumber = 0; + for (const lotOccupantType of lotOccupantTypes) { + if (lotOccupantType.orderNumber !== expectedOrderNumber) { + database.prepare("update LotOccupantTypes" + + " set orderNumber = ?" + + " where lotOccupantTypeId = ?") + .run(expectedOrderNumber, lotOccupantType.lotOccupantTypeId); + lotOccupantType.orderNumber = expectedOrderNumber; + } + expectedOrderNumber += 1; + } database.close(); return lotOccupantTypes; }; diff --git a/helpers/lotOccupancyDB/getLotOccupantTypes.ts b/helpers/lotOccupancyDB/getLotOccupantTypes.ts index 28716180..2dd45341 100644 --- a/helpers/lotOccupancyDB/getLotOccupantTypes.ts +++ b/helpers/lotOccupancyDB/getLotOccupantTypes.ts @@ -9,9 +9,7 @@ import type * as recordTypes from "../../types/recordTypes"; export const getLotOccupantTypes = (): recordTypes.LotOccupantType[] => { - const database = sqlite(databasePath, { - readonly: true - }); + const database = sqlite(databasePath); const lotOccupantTypes: recordTypes.LotOccupantType[] = database .prepare("select lotOccupantTypeId, lotOccupantType" + @@ -20,6 +18,24 @@ export const getLotOccupantTypes = (): recordTypes.LotOccupantType[] => { " order by orderNumber, lotOccupantType") .all(); + let expectedOrderNumber = 0; + + for (const lotOccupantType of lotOccupantTypes) { + + if (lotOccupantType.orderNumber !== expectedOrderNumber) { + + database.prepare("update LotOccupantTypes" + + " set orderNumber = ?" + + " where lotOccupantTypeId = ?") + .run(expectedOrderNumber, + lotOccupantType.lotOccupantTypeId); + + lotOccupantType.orderNumber = expectedOrderNumber; + } + + expectedOrderNumber += 1; + } + database.close(); return lotOccupantTypes; diff --git a/helpers/lotOccupancyDB/moveLotOccupantTypeDown.d.ts b/helpers/lotOccupancyDB/moveLotOccupantTypeDown.d.ts new file mode 100644 index 00000000..00db11d3 --- /dev/null +++ b/helpers/lotOccupancyDB/moveLotOccupantTypeDown.d.ts @@ -0,0 +1,2 @@ +export declare const moveLotOccupantTypeDown: (lotOccupantTypeId: number | string) => boolean; +export default moveLotOccupantTypeDown; diff --git a/helpers/lotOccupancyDB/moveLotOccupantTypeDown.js b/helpers/lotOccupancyDB/moveLotOccupantTypeDown.js new file mode 100644 index 00000000..b95083c2 --- /dev/null +++ b/helpers/lotOccupancyDB/moveLotOccupantTypeDown.js @@ -0,0 +1,26 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { clearLotOccupantTypesCache } from "../functions.cache.js"; +export const moveLotOccupantTypeDown = (lotOccupantTypeId) => { + const database = sqlite(databasePath); + const currentOrderNumber = database.prepare("select orderNumber" + + " from LotOccupantTypes" + + " where lotOccupantTypeId = ?") + .get(lotOccupantTypeId) + .orderNumber; + database + .prepare("update LotOccupantTypes" + + " set orderNumber = orderNumber - 1" + + " where recordDelete_timeMillis is null" + + " and orderNumber = ? + 1") + .run(currentOrderNumber); + const result = database + .prepare("update LotOccupantTypes" + + " set orderNumber = ? + 1" + + " where lotOccupantTypeId = ?") + .run(currentOrderNumber, lotOccupantTypeId); + database.close(); + clearLotOccupantTypesCache(); + return result.changes > 0; +}; +export default moveLotOccupantTypeDown; diff --git a/helpers/lotOccupancyDB/moveLotOccupantTypeDown.ts b/helpers/lotOccupancyDB/moveLotOccupantTypeDown.ts new file mode 100644 index 00000000..e2683c18 --- /dev/null +++ b/helpers/lotOccupancyDB/moveLotOccupantTypeDown.ts @@ -0,0 +1,44 @@ +import sqlite from "better-sqlite3"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; + +import { + clearLotOccupantTypesCache +} from "../functions.cache.js"; + + +export const moveLotOccupantTypeDown = + (lotOccupantTypeId: number | string): boolean => { + + const database = sqlite(databasePath); + + const currentOrderNumber: number = database.prepare("select orderNumber" + + " from LotOccupantTypes" + + " where lotOccupantTypeId = ?") + .get(lotOccupantTypeId) + .orderNumber; + + database + .prepare("update LotOccupantTypes" + + " set orderNumber = orderNumber - 1" + + " where recordDelete_timeMillis is null" + + " and orderNumber = ? + 1") + .run(currentOrderNumber); + + const result = database + .prepare("update LotOccupantTypes" + + " set orderNumber = ? + 1" + + " where lotOccupantTypeId = ?") + .run(currentOrderNumber, lotOccupantTypeId); + + database.close(); + + clearLotOccupantTypesCache(); + + return result.changes > 0; + }; + + +export default moveLotOccupantTypeDown; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/moveLotOccupantTypeUp.d.ts b/helpers/lotOccupancyDB/moveLotOccupantTypeUp.d.ts new file mode 100644 index 00000000..50aaaaf3 --- /dev/null +++ b/helpers/lotOccupancyDB/moveLotOccupantTypeUp.d.ts @@ -0,0 +1,2 @@ +export declare const moveLotOccupantTypeUp: (lotOccupantTypeId: number | string) => boolean; +export default moveLotOccupantTypeUp; diff --git a/helpers/lotOccupancyDB/moveLotOccupantTypeUp.js b/helpers/lotOccupancyDB/moveLotOccupantTypeUp.js new file mode 100644 index 00000000..c8cebf7b --- /dev/null +++ b/helpers/lotOccupancyDB/moveLotOccupantTypeUp.js @@ -0,0 +1,30 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { clearLotOccupantTypesCache } from "../functions.cache.js"; +export const moveLotOccupantTypeUp = (lotOccupantTypeId) => { + const database = sqlite(databasePath); + const currentOrderNumber = database.prepare("select orderNumber" + + " from LotOccupantTypes" + + " where lotOccupantTypeId = ?") + .get(lotOccupantTypeId) + .orderNumber; + if (currentOrderNumber <= 0) { + database.close(); + return true; + } + database + .prepare("update LotOccupantTypes" + + " set orderNumber = orderNumber + 1" + + " where recordDelete_timeMillis is null" + + " and orderNumber = ? - 1") + .run(currentOrderNumber); + const result = database + .prepare("update LotOccupantTypes" + + " set orderNumber = ? - 1" + + " where lotOccupantTypeId = ?") + .run(currentOrderNumber, lotOccupantTypeId); + database.close(); + clearLotOccupantTypesCache(); + return result.changes > 0; +}; +export default moveLotOccupantTypeUp; diff --git a/helpers/lotOccupancyDB/moveLotOccupantTypeUp.ts b/helpers/lotOccupancyDB/moveLotOccupantTypeUp.ts new file mode 100644 index 00000000..0996b964 --- /dev/null +++ b/helpers/lotOccupancyDB/moveLotOccupantTypeUp.ts @@ -0,0 +1,49 @@ +import sqlite from "better-sqlite3"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; + +import { + clearLotOccupantTypesCache +} from "../functions.cache.js"; + + +export const moveLotOccupantTypeUp = + (lotOccupantTypeId: number | string): boolean => { + + const database = sqlite(databasePath); + + const currentOrderNumber: number = database.prepare("select orderNumber" + + " from LotOccupantTypes" + + " where lotOccupantTypeId = ?") + .get(lotOccupantTypeId) + .orderNumber; + + if (currentOrderNumber <= 0) { + database.close(); + return true; + } + + database + .prepare("update LotOccupantTypes" + + " set orderNumber = orderNumber + 1" + + " where recordDelete_timeMillis is null" + + " and orderNumber = ? - 1") + .run(currentOrderNumber); + + const result = database + .prepare("update LotOccupantTypes" + + " set orderNumber = ? - 1" + + " where lotOccupantTypeId = ?") + .run(currentOrderNumber, lotOccupantTypeId); + + database.close(); + + clearLotOccupantTypesCache(); + + return result.changes > 0; + }; + + +export default moveLotOccupantTypeUp; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/updateLotOccupantType.d.ts b/helpers/lotOccupancyDB/updateLotOccupantType.d.ts new file mode 100644 index 00000000..bd5a7c49 --- /dev/null +++ b/helpers/lotOccupancyDB/updateLotOccupantType.d.ts @@ -0,0 +1,7 @@ +import type * as recordTypes from "../../types/recordTypes"; +interface UpdateLotOccupantTypeForm { + lotOccupantTypeId: number | string; + lotOccupantType: string; +} +export declare const updateLotOccupantType: (lotOccupantTypeForm: UpdateLotOccupantTypeForm, requestSession: recordTypes.PartialSession) => boolean; +export default updateLotOccupantType; diff --git a/helpers/lotOccupancyDB/updateLotOccupantType.js b/helpers/lotOccupancyDB/updateLotOccupantType.js new file mode 100644 index 00000000..7bdb4e27 --- /dev/null +++ b/helpers/lotOccupancyDB/updateLotOccupantType.js @@ -0,0 +1,19 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { clearLotOccupantTypesCache } from "../functions.cache.js"; +export const updateLotOccupantType = (lotOccupantTypeForm, requestSession) => { + const database = sqlite(databasePath); + const rightNowMillis = Date.now(); + const result = database + .prepare("update LotOccupantTypes" + + " set lotOccupantType = ?," + + " recordUpdate_userName = ?," + + " recordUpdate_timeMillis = ?" + + " where lotOccupantTypeId = ?" + + " and recordDelete_timeMillis is null") + .run(lotOccupantTypeForm.lotOccupantType, requestSession.user.userName, rightNowMillis, lotOccupantTypeForm.lotOccupantTypeId); + database.close(); + clearLotOccupantTypesCache(); + return result.changes > 0; +}; +export default updateLotOccupantType; diff --git a/helpers/lotOccupancyDB/updateLotOccupantType.ts b/helpers/lotOccupancyDB/updateLotOccupantType.ts new file mode 100644 index 00000000..4de68af7 --- /dev/null +++ b/helpers/lotOccupancyDB/updateLotOccupantType.ts @@ -0,0 +1,47 @@ +import sqlite from "better-sqlite3"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; + +import { + clearLotOccupantTypesCache +} from "../functions.cache.js"; + +import type * as recordTypes from "../../types/recordTypes"; + + +interface UpdateLotOccupantTypeForm { + lotOccupantTypeId: number | string; + lotOccupantType: string; +} + + +export const updateLotOccupantType = + (lotOccupantTypeForm: UpdateLotOccupantTypeForm, requestSession: recordTypes.PartialSession): boolean => { + + const database = sqlite(databasePath); + + const rightNowMillis = Date.now(); + + const result = database + .prepare("update LotOccupantTypes" + + " set lotOccupantType = ?," + + " recordUpdate_userName = ?," + + " recordUpdate_timeMillis = ?" + + " where lotOccupantTypeId = ?" + + " and recordDelete_timeMillis is null") + .run(lotOccupantTypeForm.lotOccupantType, + requestSession.user.userName, + rightNowMillis, + lotOccupantTypeForm.lotOccupantTypeId); + + database.close(); + + clearLotOccupantTypesCache(); + + return result.changes > 0; + }; + + +export default updateLotOccupantType; \ No newline at end of file diff --git a/public-typescript/adminTables.js b/public-typescript/adminTables.js index 9195505e..bd031a07 100644 --- a/public-typescript/adminTables.js +++ b/public-typescript/adminTables.js @@ -352,4 +352,181 @@ Object.defineProperty(exports, "__esModule", { value: true }); }); }); renderLotStatuses(); + let lotOccupantTypes = exports.lotOccupantTypes; + delete exports.lotOccupantTypes; + const updateLotOccupantType = (submitEvent) => { + submitEvent.preventDefault(); + cityssm.postJSON(urlPrefix + "/admin/doUpdateLotOccupantType", submitEvent.currentTarget, (responseJSON) => { + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + bulmaJS.alert({ + message: exports.aliases.lot + " " + exports.aliases.occupant + " Type Updated Successfully", + contextualColorName: "success" + }); + } + else { + bulmaJS.alert({ + title: "Error Updating " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + const deleteLotOccupantType = (clickEvent) => { + const tableRowElement = clickEvent.currentTarget.closest("tr"); + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; + const doDelete = () => { + cityssm.postJSON(urlPrefix + "/admin/doDeleteLotOccupantType", { + lotOccupantTypeId + }, (responseJSON) => { + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + if (lotOccupantTypes.length === 0) { + renderLotOccupantTypes(); + } + else { + tableRowElement.remove(); + } + bulmaJS.alert({ + message: exports.aliases.lot + " " + exports.aliases.occupant + " Type Deleted Successfully", + contextualColorName: "success" + }); + } + else { + bulmaJS.alert({ + title: "Error Deleting " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + bulmaJS.confirm({ + title: "Delete " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: "Are you sure you want to delete this " + exports.aliases.lot.toLowerCase() + " " + exports.aliases.occupant.toLowerCase() + " type?
" + + "Note that no " + exports.aliases.lot.toLowerCase() + " " + exports.aliases.occupancy.toLowerCase() + " will be removed.", + messageIsHtml: true, + contextualColorName: "warning", + okButton: { + text: "Yes, Delete " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + callbackFunction: doDelete + } + }); + }; + const moveLotOccupantTypeUp = (clickEvent) => { + const tableRowElement = clickEvent.currentTarget.closest("tr"); + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; + cityssm.postJSON(urlPrefix + "/admin/doMoveLotOccupantTypeUp", { + lotOccupantTypeId + }, (responseJSON) => { + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + renderLotOccupantTypes(); + } + else { + bulmaJS.alert({ + title: "Error Moving " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + const moveLotOccupantTypeDown = (clickEvent) => { + const tableRowElement = clickEvent.currentTarget.closest("tr"); + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; + cityssm.postJSON(urlPrefix + "/admin/doMoveLotOccupantTypeDown", { + lotOccupantTypeId + }, (responseJSON) => { + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + renderLotOccupantTypes(); + } + else { + bulmaJS.alert({ + title: "Error Moving " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + const renderLotOccupantTypes = () => { + const containerElement = document.querySelector("#container--lotOccupantTypes"); + if (workOrderTypes.length === 0) { + containerElement.innerHTML = "" + + "" + + "
" + + "

There are no active " + cityssm.escapeHTML(exports.aliases.lot.toLowerCase()) + " " + cityssm.escapeHTML(exports.aliases.occupant.toLowerCase()) + " types.

" + + "
" + + "" + + ""; + return; + } + containerElement.innerHTML = ""; + for (const lotOccupantType of lotOccupantTypes) { + const tableRowElement = document.createElement("tr"); + tableRowElement.dataset.lotOccupantTypeId = lotOccupantType.lotOccupantTypeId.toString(); + tableRowElement.innerHTML = "" + + "
" + + "" + + ("
" + + "
" + + "" + + "
" + + "
" + + "" + + "
" + + "
") + + "
" + + "" + + "" + + "
" + + "
" + + ("
" + + "
" + + "" + + "
" + + "
" + + "" + + "
" + + "
") + + "
" + + "
" + + "" + + "
" + + "
" + + ""; + tableRowElement.querySelector("form").addEventListener("submit", updateLotOccupantType); + tableRowElement.querySelector(".button--moveLotOccupantTypeUp").addEventListener("click", moveLotOccupantTypeUp); + tableRowElement.querySelector(".button--moveLotOccupantTypeDown").addEventListener("click", moveLotOccupantTypeDown); + tableRowElement.querySelector(".button--deleteLotOccupantType").addEventListener("click", deleteLotOccupantType); + containerElement.append(tableRowElement); + } + }; + document.querySelector("#form--addLotOccupantType").addEventListener("submit", (submitEvent) => { + submitEvent.preventDefault(); + const formElement = submitEvent.currentTarget; + cityssm.postJSON(urlPrefix + "/admin/doAddLotOccupantType", formElement, (responseJSON) => { + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + renderLotOccupantTypes(); + formElement.reset(); + formElement.querySelector("input").focus(); + } + else { + bulmaJS.alert({ + title: "Error Adding " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }); + renderLotOccupantTypes(); })(); diff --git a/public-typescript/adminTables.ts b/public-typescript/adminTables.ts index 1f20b37a..91a485ba 100644 --- a/public-typescript/adminTables.ts +++ b/public-typescript/adminTables.ts @@ -80,12 +80,12 @@ declare const bulmaJS: BulmaJS; } else { tableRowElement.remove(); } - + bulmaJS.alert({ message: "Work Order Type Deleted Successfully", contextualColorName: "success" }); - + } else { bulmaJS.alert({ title: "Error Deleting Work Order Type", @@ -116,27 +116,27 @@ declare const bulmaJS: BulmaJS; const workOrderTypeId = tableRowElement.dataset.workOrderTypeId; cityssm.postJSON(urlPrefix + "/admin/doMoveWorkOrderTypeUp", { - workOrderTypeId - }, - (responseJSON: { - success: boolean; - errorMessage ? : string; - workOrderTypes ? : recordTypes.WorkOrderType[]; - }) => { + workOrderTypeId + }, + (responseJSON: { + success: boolean; + errorMessage ? : string; + workOrderTypes ? : recordTypes.WorkOrderType[]; + }) => { - if (responseJSON.success) { + if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - renderWorkOrderTypes(); + workOrderTypes = responseJSON.workOrderTypes; + renderWorkOrderTypes(); - } else { - bulmaJS.alert({ - title: "Error Moving Work Order Type", - message: responseJSON.errorMessage, - contextualColorName: "danger" - }); - } - }); + } else { + bulmaJS.alert({ + title: "Error Moving Work Order Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); }; const moveWorkOrderTypeDown = (clickEvent: Event) => { @@ -146,27 +146,27 @@ declare const bulmaJS: BulmaJS; const workOrderTypeId = tableRowElement.dataset.workOrderTypeId; cityssm.postJSON(urlPrefix + "/admin/doMoveWorkOrderTypeDown", { - workOrderTypeId - }, - (responseJSON: { - success: boolean; - errorMessage ? : string; - workOrderTypes ? : recordTypes.WorkOrderType[]; - }) => { + workOrderTypeId + }, + (responseJSON: { + success: boolean; + errorMessage ? : string; + workOrderTypes ? : recordTypes.WorkOrderType[]; + }) => { - if (responseJSON.success) { + if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - renderWorkOrderTypes(); + workOrderTypes = responseJSON.workOrderTypes; + renderWorkOrderTypes(); - } else { - bulmaJS.alert({ - title: "Error Moving Work Order Type", - message: responseJSON.errorMessage, - contextualColorName: "danger" - }); - } - }); + } else { + bulmaJS.alert({ + title: "Error Moving Work Order Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); }; const renderWorkOrderTypes = () => { @@ -330,12 +330,12 @@ declare const bulmaJS: BulmaJS; } else { tableRowElement.remove(); } - + bulmaJS.alert({ message: exports.aliases.lot + " Status Deleted Successfully", contextualColorName: "success" }); - + } else { bulmaJS.alert({ title: "Error Deleting " + exports.aliases.lot + " Status", @@ -366,27 +366,27 @@ declare const bulmaJS: BulmaJS; const lotStatusId = tableRowElement.dataset.lotStatusId; cityssm.postJSON(urlPrefix + "/admin/doMoveLotStatusUp", { - lotStatusId - }, - (responseJSON: { - success: boolean; - errorMessage ? : string; - lotStatuses ? : recordTypes.LotStatus[]; - }) => { + lotStatusId + }, + (responseJSON: { + success: boolean; + errorMessage ? : string; + lotStatuses ? : recordTypes.LotStatus[]; + }) => { - if (responseJSON.success) { + if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - renderLotStatuses(); + lotStatuses = responseJSON.lotStatuses; + renderLotStatuses(); - } else { - bulmaJS.alert({ - title: "Error Moving " + exports.aliases.lot + " Status", - message: responseJSON.errorMessage, - contextualColorName: "danger" - }); - } - }); + } else { + bulmaJS.alert({ + title: "Error Moving " + exports.aliases.lot + " Status", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); }; const moveLotStatusDown = (clickEvent: Event) => { @@ -396,27 +396,27 @@ declare const bulmaJS: BulmaJS; const lotStatusId = tableRowElement.dataset.lotStatusId; cityssm.postJSON(urlPrefix + "/admin/doMoveLotStatusDown", { - lotStatusId - }, - (responseJSON: { - success: boolean; - errorMessage ? : string; - lotStatuses ? : recordTypes.LotStatus[]; - }) => { + lotStatusId + }, + (responseJSON: { + success: boolean; + errorMessage ? : string; + lotStatuses ? : recordTypes.LotStatus[]; + }) => { - if (responseJSON.success) { + if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - renderLotStatuses(); + lotStatuses = responseJSON.lotStatuses; + renderLotStatuses(); - } else { - bulmaJS.alert({ - title: "Error Moving " + exports.aliases.lot + " Status", - message: responseJSON.errorMessage, - contextualColorName: "danger" - }); - } - }); + } else { + bulmaJS.alert({ + title: "Error Moving " + exports.aliases.lot + " Status", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); }; const renderLotStatuses = () => { @@ -516,4 +516,257 @@ declare const bulmaJS: BulmaJS; }); renderLotStatuses(); + + /* + * Lot Occupant Types + */ + + + let lotOccupantTypes: recordTypes.LotOccupantType[] = exports.lotOccupantTypes; + delete exports.lotOccupantTypes; + + const updateLotOccupantType = (submitEvent: SubmitEvent) => { + + submitEvent.preventDefault(); + + cityssm.postJSON(urlPrefix + "/admin/doUpdateLotOccupantType", + submitEvent.currentTarget, + (responseJSON: { + success: boolean; + errorMessage ? : string; + lotOccupantTypes ? : recordTypes.LotOccupantType[]; + }) => { + if (responseJSON.success) { + + lotOccupantTypes = responseJSON.lotOccupantTypes; + + bulmaJS.alert({ + message: exports.aliases.lot + " " + exports.aliases.occupant + " Type Updated Successfully", + contextualColorName: "success" + }); + + } else { + bulmaJS.alert({ + title: "Error Updating " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + + const deleteLotOccupantType = (clickEvent: Event) => { + + const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest("tr"); + + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; + + const doDelete = () => { + + cityssm.postJSON(urlPrefix + "/admin/doDeleteLotOccupantType", { + lotOccupantTypeId + }, + (responseJSON: { + success: boolean; + errorMessage ? : string; + lotOccupantTypes ? : recordTypes.LotOccupantType[]; + }) => { + + if (responseJSON.success) { + + lotOccupantTypes = responseJSON.lotOccupantTypes; + + if (lotOccupantTypes.length === 0) { + renderLotOccupantTypes(); + } else { + tableRowElement.remove(); + } + + bulmaJS.alert({ + message: exports.aliases.lot + " " + exports.aliases.occupant + " Type Deleted Successfully", + contextualColorName: "success" + }); + + } else { + bulmaJS.alert({ + title: "Error Deleting " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + + bulmaJS.confirm({ + title: "Delete " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: "Are you sure you want to delete this " + exports.aliases.lot.toLowerCase() + " " + exports.aliases.occupant.toLowerCase() + " type?
" + + "Note that no " + exports.aliases.lot.toLowerCase() + " " + exports.aliases.occupancy.toLowerCase() + " will be removed.", + messageIsHtml: true, + contextualColorName: "warning", + okButton: { + text: "Yes, Delete " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + callbackFunction: doDelete + } + }); + }; + + const moveLotOccupantTypeUp = (clickEvent: Event) => { + + const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest("tr"); + + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; + + cityssm.postJSON(urlPrefix + "/admin/doMoveLotOccupantTypeUp", { + lotOccupantTypeId + }, + (responseJSON: { + success: boolean; + errorMessage ? : string; + lotOccupantTypes ? : recordTypes.LotOccupantType[]; + }) => { + + if (responseJSON.success) { + + lotOccupantTypes = responseJSON.lotOccupantTypes; + renderLotOccupantTypes(); + + } else { + bulmaJS.alert({ + title: "Error Moving " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + + const moveLotOccupantTypeDown = (clickEvent: Event) => { + + const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest("tr"); + + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; + + cityssm.postJSON(urlPrefix + "/admin/doMoveLotOccupantTypeDown", { + lotOccupantTypeId + }, + (responseJSON: { + success: boolean; + errorMessage ? : string; + lotOccupantTypes ? : recordTypes.LotOccupantType[]; + }) => { + + if (responseJSON.success) { + + lotOccupantTypes = responseJSON.lotOccupantTypes; + renderLotOccupantTypes(); + + } else { + bulmaJS.alert({ + title: "Error Moving " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + + const renderLotOccupantTypes = () => { + + const containerElement = document.querySelector("#container--lotOccupantTypes") as HTMLTableSectionElement; + + if (workOrderTypes.length === 0) { + containerElement.innerHTML = "" + + "" + + "
" + + "

There are no active " + cityssm.escapeHTML(exports.aliases.lot.toLowerCase()) + " " + cityssm.escapeHTML(exports.aliases.occupant.toLowerCase()) + " types.

" + + "
" + + "" + + ""; + + return; + } + + containerElement.innerHTML = ""; + + for (const lotOccupantType of lotOccupantTypes) { + + const tableRowElement = document.createElement("tr"); + + tableRowElement.dataset.lotOccupantTypeId = lotOccupantType.lotOccupantTypeId.toString(); + + tableRowElement.innerHTML = "" + + "
" + + "" + + ("
" + + "
" + + "" + + "
" + + "
" + + "" + + "
" + + "
") + + "
" + + "" + + "" + + "
" + + "
" + + ("
" + + "
" + + "" + + "
" + + "
" + + "" + + "
" + + "
") + + "
" + + "
" + + "" + + "
" + + "
" + + ""; + + tableRowElement.querySelector("form").addEventListener("submit", updateLotOccupantType); + tableRowElement.querySelector(".button--moveLotOccupantTypeUp").addEventListener("click", moveLotOccupantTypeUp); + tableRowElement.querySelector(".button--moveLotOccupantTypeDown").addEventListener("click", moveLotOccupantTypeDown); + tableRowElement.querySelector(".button--deleteLotOccupantType").addEventListener("click", deleteLotOccupantType); + + containerElement.append(tableRowElement); + } + + }; + + document.querySelector("#form--addLotOccupantType").addEventListener("submit", (submitEvent: SubmitEvent) => { + + submitEvent.preventDefault(); + + const formElement = submitEvent.currentTarget as HTMLFormElement; + + cityssm.postJSON(urlPrefix + "/admin/doAddLotOccupantType", + formElement, + (responseJSON: { + success: boolean; + errorMessage ? : string; + lotOccupantTypes ? : recordTypes.LotOccupantType[]; + }) => { + + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + renderLotOccupantTypes(); + formElement.reset(); + formElement.querySelector("input").focus(); + } else { + bulmaJS.alert({ + title: "Error Adding " + exports.aliases.lot + " " + exports.aliases.occupant + " Type", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }); + + renderLotOccupantTypes(); })(); \ No newline at end of file diff --git a/public/javascripts/adminTables.min.js b/public/javascripts/adminTables.min.js index c89953b9..76b460a5 100644 --- a/public/javascripts/adminTables.min.js +++ b/public/javascripts/adminTables.min.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix;let t=exports.workOrderTypes;delete exports.workOrderTypes;const s=s=>{s.preventDefault(),cityssm.postJSON(e+"/admin/doUpdateWorkOrderType",s.currentTarget,e=>{e.success?(t=e.workOrderTypes,bulmaJS.alert({message:"Work Order Type Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Updating Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})},r=s=>{const r=s.currentTarget.closest("tr"),o=r.dataset.workOrderTypeId;bulmaJS.confirm({title:"Delete Work Order Type",message:"Are you sure you want to delete this work order type?
Note that no work orders will be removed.",messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Delete Work Order Type",callbackFunction:()=>{cityssm.postJSON(e+"/admin/doDeleteWorkOrderType",{workOrderTypeId:o},e=>{e.success?(0===(t=e.workOrderTypes).length?l():r.remove(),bulmaJS.alert({message:"Work Order Type Deleted Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Deleting Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})}}})},o=s=>{const r=s.currentTarget.closest("tr").dataset.workOrderTypeId;cityssm.postJSON(e+"/admin/doMoveWorkOrderTypeUp",{workOrderTypeId:r},e=>{e.success?(t=e.workOrderTypes,l()):bulmaJS.alert({title:"Error Moving Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})},a=s=>{const r=s.currentTarget.closest("tr").dataset.workOrderTypeId;cityssm.postJSON(e+"/admin/doMoveWorkOrderTypeDown",{workOrderTypeId:r},e=>{e.success?(t=e.workOrderTypes,l()):bulmaJS.alert({title:"Error Moving Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})},l=()=>{const e=document.querySelector("#container--workOrderTypes");if(0!==t.length){e.innerHTML="";for(const l of t){const t=document.createElement("tr");t.dataset.workOrderTypeId=l.workOrderTypeId.toString(),t.innerHTML='
',t.querySelector("form").addEventListener("submit",s),t.querySelector(".button--moveWorkOrderTypeUp").addEventListener("click",o),t.querySelector(".button--moveWorkOrderTypeDown").addEventListener("click",a),t.querySelector(".button--deleteWorkOrderType").addEventListener("click",r),e.append(t)}}else e.innerHTML='

There are no active work order types.

'};document.querySelector("#form--addWorkOrderType").addEventListener("submit",s=>{s.preventDefault();const r=s.currentTarget;cityssm.postJSON(e+"/admin/doAddWorkOrderType",r,e=>{e.success?(t=e.workOrderTypes,l(),r.reset(),r.querySelector("input").focus()):bulmaJS.alert({title:"Error Adding Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})}),l();let d=exports.lotStatuses;delete exports.lotStatuses;const n=t=>{t.preventDefault(),cityssm.postJSON(e+"/admin/doUpdateLotStatus",t.currentTarget,e=>{e.success?(d=e.lotStatuses,bulmaJS.alert({message:exports.aliases.lot+" Status Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Updating "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})},u=t=>{const s=t.currentTarget.closest("tr"),r=s.dataset.lotStatusId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" Status",message:"Are you sure you want to delete this status?
Note that no "+exports.aliases.lots.toLowerCase()+" will be removed.",messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Delete Status",callbackFunction:()=>{cityssm.postJSON(e+"/admin/doDeleteLotStatus",{lotStatusId:r},e=>{e.success?(0===(d=e.lotStatuses).length?p():s.remove(),bulmaJS.alert({message:exports.aliases.lot+" Status Deleted Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Deleting "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})}}})},i=t=>{const s=t.currentTarget.closest("tr").dataset.lotStatusId;cityssm.postJSON(e+"/admin/doMoveLotStatusUp",{lotStatusId:s},e=>{e.success?(d=e.lotStatuses,p()):bulmaJS.alert({title:"Error Moving "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})},c=t=>{const s=t.currentTarget.closest("tr").dataset.lotStatusId;cityssm.postJSON(e+"/admin/doMoveLotStatusDown",{lotStatusId:s},e=>{e.success?(d=e.lotStatuses,p()):bulmaJS.alert({title:"Error Moving "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})},p=()=>{const e=document.querySelector("#container--lotStatuses");if(0!==t.length){e.innerHTML="";for(const t of d){const s=document.createElement("tr");s.dataset.lotStatusId=t.lotStatusId.toString(),s.innerHTML='
',s.querySelector("form").addEventListener("submit",n),s.querySelector(".button--moveLotStatusUp").addEventListener("click",i),s.querySelector(".button--moveLotStatusDown").addEventListener("click",c),s.querySelector(".button--deleteLotStatus").addEventListener("click",u),e.append(s)}}else e.innerHTML='

There are no active '+cityssm.escapeHTML(exports.aliases.lot.toLowerCase())+" statuses.

"};document.querySelector("#form--addLotStatus").addEventListener("submit",t=>{t.preventDefault();const s=t.currentTarget;cityssm.postJSON(e+"/admin/doAddLotStatus",s,e=>{e.success?(d=e.lotStatuses,p(),s.reset(),s.querySelector("input").focus()):bulmaJS.alert({title:"Error Adding "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})}),p()})(); \ No newline at end of file +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix;let t=exports.workOrderTypes;delete exports.workOrderTypes;const s=s=>{s.preventDefault(),cityssm.postJSON(e+"/admin/doUpdateWorkOrderType",s.currentTarget,e=>{e.success?(t=e.workOrderTypes,bulmaJS.alert({message:"Work Order Type Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Updating Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})},o=s=>{const o=s.currentTarget.closest("tr"),a=o.dataset.workOrderTypeId;bulmaJS.confirm({title:"Delete Work Order Type",message:"Are you sure you want to delete this work order type?
Note that no work orders will be removed.",messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Delete Work Order Type",callbackFunction:()=>{cityssm.postJSON(e+"/admin/doDeleteWorkOrderType",{workOrderTypeId:a},e=>{e.success?(0===(t=e.workOrderTypes).length?l():o.remove(),bulmaJS.alert({message:"Work Order Type Deleted Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Deleting Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})}}})},a=s=>{const o=s.currentTarget.closest("tr").dataset.workOrderTypeId;cityssm.postJSON(e+"/admin/doMoveWorkOrderTypeUp",{workOrderTypeId:o},e=>{e.success?(t=e.workOrderTypes,l()):bulmaJS.alert({title:"Error Moving Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})},r=s=>{const o=s.currentTarget.closest("tr").dataset.workOrderTypeId;cityssm.postJSON(e+"/admin/doMoveWorkOrderTypeDown",{workOrderTypeId:o},e=>{e.success?(t=e.workOrderTypes,l()):bulmaJS.alert({title:"Error Moving Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})},l=()=>{const e=document.querySelector("#container--workOrderTypes");if(0!==t.length){e.innerHTML="";for(const l of t){const t=document.createElement("tr");t.dataset.workOrderTypeId=l.workOrderTypeId.toString(),t.innerHTML='
',t.querySelector("form").addEventListener("submit",s),t.querySelector(".button--moveWorkOrderTypeUp").addEventListener("click",a),t.querySelector(".button--moveWorkOrderTypeDown").addEventListener("click",r),t.querySelector(".button--deleteWorkOrderType").addEventListener("click",o),e.append(t)}}else e.innerHTML='

There are no active work order types.

'};document.querySelector("#form--addWorkOrderType").addEventListener("submit",s=>{s.preventDefault();const o=s.currentTarget;cityssm.postJSON(e+"/admin/doAddWorkOrderType",o,e=>{e.success?(t=e.workOrderTypes,l(),o.reset(),o.querySelector("input").focus()):bulmaJS.alert({title:"Error Adding Work Order Type",message:e.errorMessage,contextualColorName:"danger"})})}),l();let n=exports.lotStatuses;delete exports.lotStatuses;const c=t=>{t.preventDefault(),cityssm.postJSON(e+"/admin/doUpdateLotStatus",t.currentTarget,e=>{e.success?(n=e.lotStatuses,bulmaJS.alert({message:exports.aliases.lot+" Status Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Updating "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})},d=t=>{const s=t.currentTarget.closest("tr"),o=s.dataset.lotStatusId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" Status",message:"Are you sure you want to delete this status?
Note that no "+exports.aliases.lots.toLowerCase()+" will be removed.",messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Delete Status",callbackFunction:()=>{cityssm.postJSON(e+"/admin/doDeleteLotStatus",{lotStatusId:o},e=>{e.success?(0===(n=e.lotStatuses).length?p():s.remove(),bulmaJS.alert({message:exports.aliases.lot+" Status Deleted Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Deleting "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})}}})},i=t=>{const s=t.currentTarget.closest("tr").dataset.lotStatusId;cityssm.postJSON(e+"/admin/doMoveLotStatusUp",{lotStatusId:s},e=>{e.success?(n=e.lotStatuses,p()):bulmaJS.alert({title:"Error Moving "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})},u=t=>{const s=t.currentTarget.closest("tr").dataset.lotStatusId;cityssm.postJSON(e+"/admin/doMoveLotStatusDown",{lotStatusId:s},e=>{e.success?(n=e.lotStatuses,p()):bulmaJS.alert({title:"Error Moving "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})},p=()=>{const e=document.querySelector("#container--lotStatuses");if(0!==t.length){e.innerHTML="";for(const t of n){const s=document.createElement("tr");s.dataset.lotStatusId=t.lotStatusId.toString(),s.innerHTML='
',s.querySelector("form").addEventListener("submit",c),s.querySelector(".button--moveLotStatusUp").addEventListener("click",i),s.querySelector(".button--moveLotStatusDown").addEventListener("click",u),s.querySelector(".button--deleteLotStatus").addEventListener("click",d),e.append(s)}}else e.innerHTML='

There are no active '+cityssm.escapeHTML(exports.aliases.lot.toLowerCase())+" statuses.

"};document.querySelector("#form--addLotStatus").addEventListener("submit",t=>{t.preventDefault();const s=t.currentTarget;cityssm.postJSON(e+"/admin/doAddLotStatus",s,e=>{e.success?(n=e.lotStatuses,p(),s.reset(),s.querySelector("input").focus()):bulmaJS.alert({title:"Error Adding "+exports.aliases.lot+" Status",message:e.errorMessage,contextualColorName:"danger"})})}),p();let m=exports.lotOccupantTypes;delete exports.lotOccupantTypes;const y=t=>{t.preventDefault(),cityssm.postJSON(e+"/admin/doUpdateLotOccupantType",t.currentTarget,e=>{e.success?(m=e.lotOccupantTypes,bulmaJS.alert({message:exports.aliases.lot+" "+exports.aliases.occupant+" Type Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Updating "+exports.aliases.lot+" "+exports.aliases.occupant+" Type",message:e.errorMessage,contextualColorName:"danger"})})},v=t=>{const s=t.currentTarget.closest("tr"),o=s.dataset.lotOccupantTypeId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" "+exports.aliases.occupant+" Type",message:"Are you sure you want to delete this "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupant.toLowerCase()+" type?
Note that no "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupancy.toLowerCase()+" will be removed.",messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Delete "+exports.aliases.lot+" "+exports.aliases.occupant+" Type",callbackFunction:()=>{cityssm.postJSON(e+"/admin/doDeleteLotOccupantType",{lotOccupantTypeId:o},e=>{e.success?(0===(m=e.lotOccupantTypes).length?b():s.remove(),bulmaJS.alert({message:exports.aliases.lot+" "+exports.aliases.occupant+" Type Deleted Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Deleting "+exports.aliases.lot+" "+exports.aliases.occupant+" Type",message:e.errorMessage,contextualColorName:"danger"})})}}})},g=t=>{const s=t.currentTarget.closest("tr").dataset.lotOccupantTypeId;cityssm.postJSON(e+"/admin/doMoveLotOccupantTypeUp",{lotOccupantTypeId:s},e=>{e.success?(m=e.lotOccupantTypes,b()):bulmaJS.alert({title:"Error Moving "+exports.aliases.lot+" "+exports.aliases.occupant+" Type",message:e.errorMessage,contextualColorName:"danger"})})},T=t=>{const s=t.currentTarget.closest("tr").dataset.lotOccupantTypeId;cityssm.postJSON(e+"/admin/doMoveLotOccupantTypeDown",{lotOccupantTypeId:s},e=>{e.success?(m=e.lotOccupantTypes,b()):bulmaJS.alert({title:"Error Moving "+exports.aliases.lot+" "+exports.aliases.occupant+" Type",message:e.errorMessage,contextualColorName:"danger"})})},b=()=>{const e=document.querySelector("#container--lotOccupantTypes");if(0!==t.length){e.innerHTML="";for(const t of m){const s=document.createElement("tr");s.dataset.lotOccupantTypeId=t.lotOccupantTypeId.toString(),s.innerHTML='
',s.querySelector("form").addEventListener("submit",y),s.querySelector(".button--moveLotOccupantTypeUp").addEventListener("click",g),s.querySelector(".button--moveLotOccupantTypeDown").addEventListener("click",T),s.querySelector(".button--deleteLotOccupantType").addEventListener("click",v),e.append(s)}}else e.innerHTML='

There are no active '+cityssm.escapeHTML(exports.aliases.lot.toLowerCase())+" "+cityssm.escapeHTML(exports.aliases.occupant.toLowerCase())+" types.

"};document.querySelector("#form--addLotOccupantType").addEventListener("submit",t=>{t.preventDefault();const s=t.currentTarget;cityssm.postJSON(e+"/admin/doAddLotOccupantType",s,e=>{e.success?(m=e.lotOccupantTypes,b(),s.reset(),s.querySelector("input").focus()):bulmaJS.alert({title:"Error Adding "+exports.aliases.lot+" "+exports.aliases.occupant+" Type",message:e.errorMessage,contextualColorName:"danger"})})}),b()})(); \ No newline at end of file diff --git a/routes/admin.js b/routes/admin.js index 446ef792..f7ad8289 100644 --- a/routes/admin.js +++ b/routes/admin.js @@ -18,6 +18,11 @@ import handler_doUpdateLotStatus from "../handlers/admin-post/doUpdateLotStatus. import handler_doMoveLotStatusUp from "../handlers/admin-post/doMoveLotStatusUp.js"; import handler_doMoveLotStatusDown from "../handlers/admin-post/doMoveLotStatusDown.js"; import handler_doDeleteLotStatus from "../handlers/admin-post/doDeleteLotStatus.js"; +import handler_doAddLotOccupantType from "../handlers/admin-post/doAddLotOccupantType.js"; +import handler_doUpdateLotOccupantType from "../handlers/admin-post/doUpdateLotOccupantType.js"; +import handler_doMoveLotOccupantTypeUp from "../handlers/admin-post/doMoveLotOccupantTypeUp.js"; +import handler_doMoveLotOccupantTypeDown from "../handlers/admin-post/doMoveLotOccupantTypeDown.js"; +import handler_doDeleteLotOccupantType from "../handlers/admin-post/doDeleteLotOccupantType.js"; export const router = Router(); router.get("/fees", permissionHandlers.adminGetHandler, handler_fees); router.post("/doAddFeeCategory", permissionHandlers.adminPostHandler, handler_doAddFeeCategory); @@ -33,8 +38,13 @@ router.post("/doMoveWorkOrderTypeUp", permissionHandlers.adminPostHandler, handl router.post("/doMoveWorkOrderTypeDown", permissionHandlers.adminPostHandler, handler_doMoveWorkOrderTypeDown); router.post("/doDeleteWorkOrderType", permissionHandlers.adminPostHandler, handler_doDeleteWorkOrderType); router.post("/doAddLotStatus", permissionHandlers.adminPostHandler, handler_doAddLotStatus); -router.post("/doUpdateLotStatuse", permissionHandlers.adminPostHandler, handler_doUpdateLotStatus); +router.post("/doUpdateLotStatus", permissionHandlers.adminPostHandler, handler_doUpdateLotStatus); router.post("/doMoveLotStatusUp", permissionHandlers.adminPostHandler, handler_doMoveLotStatusUp); router.post("/doMoveLotStatusDown", permissionHandlers.adminPostHandler, handler_doMoveLotStatusDown); router.post("/doDeleteLotStatus", permissionHandlers.adminPostHandler, handler_doDeleteLotStatus); +router.post("/doAddLotOccupantType", permissionHandlers.adminPostHandler, handler_doAddLotOccupantType); +router.post("/doUpdateLotOccupantType", permissionHandlers.adminPostHandler, handler_doUpdateLotOccupantType); +router.post("/doMoveLotOccupantTypeUp", permissionHandlers.adminPostHandler, handler_doMoveLotOccupantTypeUp); +router.post("/doMoveLotOccupantTypeDown", permissionHandlers.adminPostHandler, handler_doMoveLotOccupantTypeDown); +router.post("/doDeleteLotOccupantType", permissionHandlers.adminPostHandler, handler_doDeleteLotOccupantType); export default router; diff --git a/routes/admin.ts b/routes/admin.ts index 2b986e61..02c844f9 100644 --- a/routes/admin.ts +++ b/routes/admin.ts @@ -27,6 +27,12 @@ import handler_doMoveLotStatusUp from "../handlers/admin-post/doMoveLotStatusUp. import handler_doMoveLotStatusDown from "../handlers/admin-post/doMoveLotStatusDown.js"; import handler_doDeleteLotStatus from "../handlers/admin-post/doDeleteLotStatus.js"; +import handler_doAddLotOccupantType from "../handlers/admin-post/doAddLotOccupantType.js"; +import handler_doUpdateLotOccupantType from "../handlers/admin-post/doUpdateLotOccupantType.js"; +import handler_doMoveLotOccupantTypeUp from "../handlers/admin-post/doMoveLotOccupantTypeUp.js"; +import handler_doMoveLotOccupantTypeDown from "../handlers/admin-post/doMoveLotOccupantTypeDown.js"; +import handler_doDeleteLotOccupantType from "../handlers/admin-post/doDeleteLotOccupantType.js"; + export const router = Router(); @@ -91,12 +97,11 @@ router.post("/doDeleteWorkOrderType", // Config Tables - Lot Statuses - router.post("/doAddLotStatus", permissionHandlers.adminPostHandler, handler_doAddLotStatus); -router.post("/doUpdateLotStatuse", +router.post("/doUpdateLotStatus", permissionHandlers.adminPostHandler, handler_doUpdateLotStatus); @@ -112,5 +117,27 @@ router.post("/doDeleteLotStatus", permissionHandlers.adminPostHandler, handler_doDeleteLotStatus); +// Config Tables - Lot Occupant Types + +router.post("/doAddLotOccupantType", + permissionHandlers.adminPostHandler, + handler_doAddLotOccupantType); + +router.post("/doUpdateLotOccupantType", + permissionHandlers.adminPostHandler, + handler_doUpdateLotOccupantType); + +router.post("/doMoveLotOccupantTypeUp", + permissionHandlers.adminPostHandler, + handler_doMoveLotOccupantTypeUp); + +router.post("/doMoveLotOccupantTypeDown", + permissionHandlers.adminPostHandler, + handler_doMoveLotOccupantTypeDown); + +router.post("/doDeleteLotOccupantType", + permissionHandlers.adminPostHandler, + handler_doDeleteLotOccupantType); + export default router; \ No newline at end of file diff --git a/views/admin-tables.ejs b/views/admin-tables.ejs index 0f9a6e85..fce3b72c 100644 --- a/views/admin-tables.ejs +++ b/views/admin-tables.ejs @@ -107,6 +107,33 @@