diff --git a/handlers/lots-get/print.js b/handlers/lots-get/print.js deleted file mode 100644 index c2fa3413..00000000 --- a/handlers/lots-get/print.js +++ /dev/null @@ -1,6 +0,0 @@ -import * as configFunctions from "../../helpers/functions.config.js"; -const urlPrefix = configFunctions.getProperty("reverseProxy.urlPrefix"); -const __dirname = "."; -export const handler = async (request, response, next) => { -}; -export default handler; diff --git a/handlers/lots-get/print.ts b/handlers/lots-get/print.ts deleted file mode 100644 index 401134b8..00000000 --- a/handlers/lots-get/print.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { RequestHandler } from "express"; - -import path from "path"; -import * as ejs from "ejs"; - -import * as configFunctions from "../../helpers/functions.config.js"; - -// import convertHTMLToPDF from "pdf-puppeteer"; - - -const urlPrefix = configFunctions.getProperty("reverseProxy.urlPrefix"); - -const __dirname = "."; - - -export const handler: RequestHandler = async(request, response, next) => { - -/* - const reportPath = path.join(__dirname, "reports", printTemplate); - - const pdfCallbackFunction = (pdf: Buffer) => { - - response.setHeader("Content-Disposition", - "attachment;" + - " filename=licence-" + licenceID.toString() + "-" + licence.recordUpdate_timeMillis.toString() + ".pdf" - ); - - response.setHeader("Content-Type", "application/pdf"); - - response.send(pdf); - }; - - await ejs.renderFile( - reportPath, { - configFunctions, - licence, - licenceTicketTypeSummary, - organization - }, {}, - async(ejsError, ejsData) => { - - if (ejsError) { - return next(ejsError); - } - - await convertHTMLToPDF(ejsData, pdfCallbackFunction, { - format: "letter", - printBackground: true, - preferCSSPageSize: true - }); - - return; - } - ); - */ -}; - - -export default handler; diff --git a/handlers/lots-get/print.d.ts b/handlers/lots-post/doAddLotComment.d.ts similarity index 100% rename from handlers/lots-get/print.d.ts rename to handlers/lots-post/doAddLotComment.d.ts diff --git a/handlers/lots-post/doAddLotComment.js b/handlers/lots-post/doAddLotComment.js new file mode 100644 index 00000000..2e3bd458 --- /dev/null +++ b/handlers/lots-post/doAddLotComment.js @@ -0,0 +1,11 @@ +import { addLotComment } from "../../helpers/lotOccupancyDB/addLotComment.js"; +import { getLotComments } from "../../helpers/lotOccupancyDB/getLotComments.js"; +export const handler = async (request, response) => { + addLotComment(request.body, request.session); + const lotComments = getLotComments(request.body.lotId); + response.json({ + success: true, + lotComments + }); +}; +export default handler; diff --git a/handlers/lots-post/doAddLotComment.ts b/handlers/lots-post/doAddLotComment.ts new file mode 100644 index 00000000..9f817b9f --- /dev/null +++ b/handlers/lots-post/doAddLotComment.ts @@ -0,0 +1,27 @@ +import type { + RequestHandler +} from "express"; + +import { + addLotComment +} from "../../helpers/lotOccupancyDB/addLotComment.js"; + +import { + getLotComments +} from "../../helpers/lotOccupancyDB/getLotComments.js"; + + +export const handler: RequestHandler = async (request, response) => { + + addLotComment(request.body, request.session); + + const lotComments = getLotComments(request.body.lotId); + + response.json({ + success: true, + lotComments + }); +}; + + +export default handler; \ No newline at end of file diff --git a/handlers/lots-post/doDeleteLotComment.d.ts b/handlers/lots-post/doDeleteLotComment.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/lots-post/doDeleteLotComment.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/lots-post/doDeleteLotComment.js b/handlers/lots-post/doDeleteLotComment.js new file mode 100644 index 00000000..9af54d2f --- /dev/null +++ b/handlers/lots-post/doDeleteLotComment.js @@ -0,0 +1,11 @@ +import { deleteLotComment } from "../../helpers/lotOccupancyDB/deleteLotComment.js"; +import { getLotComments } from "../../helpers/lotOccupancyDB/getLotComments.js"; +export const handler = async (request, response) => { + const success = deleteLotComment(request.body.lotCommentId, request.session); + const lotComments = getLotComments(request.body.lotId); + response.json({ + success, + lotComments + }); +}; +export default handler; diff --git a/handlers/lots-post/doDeleteLotComment.ts b/handlers/lots-post/doDeleteLotComment.ts new file mode 100644 index 00000000..1e9aab56 --- /dev/null +++ b/handlers/lots-post/doDeleteLotComment.ts @@ -0,0 +1,27 @@ +import type { + RequestHandler +} from "express"; + +import { + deleteLotComment +} from "../../helpers/lotOccupancyDB/deleteLotComment.js"; + +import { + getLotComments +} from "../../helpers/lotOccupancyDB/getLotComments.js"; + + +export const handler: RequestHandler = async (request, response) => { + + const success = deleteLotComment(request.body.lotCommentId, request.session); + + const lotComments = getLotComments(request.body.lotId); + + response.json({ + success, + lotComments + }); +}; + + +export default handler; \ No newline at end of file diff --git a/handlers/lots-post/doUpdateLotComment.d.ts b/handlers/lots-post/doUpdateLotComment.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/lots-post/doUpdateLotComment.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/lots-post/doUpdateLotComment.js b/handlers/lots-post/doUpdateLotComment.js new file mode 100644 index 00000000..30ca5b6b --- /dev/null +++ b/handlers/lots-post/doUpdateLotComment.js @@ -0,0 +1,11 @@ +import { updateLotComment } from "../../helpers/lotOccupancyDB/updateLotComment.js"; +import { getLotComments } from "../../helpers/lotOccupancyDB/getLotComments.js"; +export const handler = async (request, response) => { + const success = updateLotComment(request.body, request.session); + const lotComments = getLotComments(request.body.lotId); + response.json({ + success, + lotComments + }); +}; +export default handler; diff --git a/handlers/lots-post/doUpdateLotComment.ts b/handlers/lots-post/doUpdateLotComment.ts new file mode 100644 index 00000000..4535e53b --- /dev/null +++ b/handlers/lots-post/doUpdateLotComment.ts @@ -0,0 +1,27 @@ +import type { + RequestHandler +} from "express"; + +import { + updateLotComment +} from "../../helpers/lotOccupancyDB/updateLotComment.js"; + +import { + getLotComments +} from "../../helpers/lotOccupancyDB/getLotComments.js"; + + +export const handler: RequestHandler = async (request, response) => { + + const success = updateLotComment(request.body, request.session); + + const lotComments = getLotComments(request.body.lotId); + + response.json({ + success, + lotComments + }); +}; + + +export default handler; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/deleteLotComment.d.ts b/helpers/lotOccupancyDB/deleteLotComment.d.ts new file mode 100644 index 00000000..0292f9a0 --- /dev/null +++ b/helpers/lotOccupancyDB/deleteLotComment.d.ts @@ -0,0 +1,3 @@ +import type * as recordTypes from "../../types/recordTypes"; +export declare const deleteLotComment: (lotCommentId: number | string, requestSession: recordTypes.PartialSession) => boolean; +export default deleteLotComment; diff --git a/helpers/lotOccupancyDB/deleteLotComment.js b/helpers/lotOccupancyDB/deleteLotComment.js new file mode 100644 index 00000000..2fbda89f --- /dev/null +++ b/helpers/lotOccupancyDB/deleteLotComment.js @@ -0,0 +1,15 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +export const deleteLotComment = (lotCommentId, requestSession) => { + const database = sqlite(databasePath); + const rightNowMillis = Date.now(); + const result = database + .prepare("update LotComments" + + " set recordDelete_userName = ?," + + " recordDelete_timeMillis = ?" + + " where lotCommentId = ?") + .run(requestSession.user.userName, rightNowMillis, lotCommentId); + database.close(); + return (result.changes > 0); +}; +export default deleteLotComment; diff --git a/helpers/lotOccupancyDB/deleteLotComment.ts b/helpers/lotOccupancyDB/deleteLotComment.ts new file mode 100644 index 00000000..46439e3e --- /dev/null +++ b/helpers/lotOccupancyDB/deleteLotComment.ts @@ -0,0 +1,33 @@ +import sqlite from "better-sqlite3"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; + +import type * as recordTypes from "../../types/recordTypes"; + + +export const deleteLotComment = + (lotCommentId: number | string, + requestSession: recordTypes.PartialSession): boolean => { + + const database = sqlite(databasePath); + + const rightNowMillis = Date.now(); + + const result = database + .prepare("update LotComments" + + " set recordDelete_userName = ?," + + " recordDelete_timeMillis = ?" + + " where lotCommentId = ?") + .run(requestSession.user.userName, + rightNowMillis, + lotCommentId); + + database.close(); + + return (result.changes > 0); + }; + + +export default deleteLotComment; \ No newline at end of file diff --git a/helpers/lotOccupancyDB/getLotComments.js b/helpers/lotOccupancyDB/getLotComments.js index 86c6d2ea..2a01d5f5 100644 --- a/helpers/lotOccupancyDB/getLotComments.js +++ b/helpers/lotOccupancyDB/getLotComments.js @@ -11,7 +11,8 @@ export const getLotComments = (lotId, connectedDatabase) => { .prepare("select lotCommentId," + " lotCommentDate, userFn_dateIntegerToString(lotCommentDate) as lotCommentDateString," + " lotCommentTime, userFn_timeIntegerToString(lotCommentTime) as lotCommentTimeString," + - " lotComment" + + " lotComment," + + " recordCreate_userName, recordUpdate_userName" + " from LotComments" + " where recordDelete_timeMillis is null" + " and lotId = ?" + diff --git a/helpers/lotOccupancyDB/getLotComments.ts b/helpers/lotOccupancyDB/getLotComments.ts index f8d9baba..6031e06b 100644 --- a/helpers/lotOccupancyDB/getLotComments.ts +++ b/helpers/lotOccupancyDB/getLotComments.ts @@ -20,7 +20,8 @@ export const getLotComments = (lotId: number | string, connectedDatabase ? : sql .prepare("select lotCommentId," + " lotCommentDate, userFn_dateIntegerToString(lotCommentDate) as lotCommentDateString," + " lotCommentTime, userFn_timeIntegerToString(lotCommentTime) as lotCommentTimeString," + - " lotComment" + + " lotComment," + + " recordCreate_userName, recordUpdate_userName" + " from LotComments" + " where recordDelete_timeMillis is null" + " and lotId = ?" + diff --git a/helpers/lotOccupancyDB/updateLotComment.d.ts b/helpers/lotOccupancyDB/updateLotComment.d.ts new file mode 100644 index 00000000..3b95fc34 --- /dev/null +++ b/helpers/lotOccupancyDB/updateLotComment.d.ts @@ -0,0 +1,9 @@ +import type * as recordTypes from "../../types/recordTypes"; +interface UpdateLotCommentForm { + lotCommentId: string | number; + lotCommentDateString: string; + lotCommentTimeString: string; + lotComment: string; +} +export declare const updateLotComment: (commentForm: UpdateLotCommentForm, requestSession: recordTypes.PartialSession) => boolean; +export default updateLotComment; diff --git a/helpers/lotOccupancyDB/updateLotComment.js b/helpers/lotOccupancyDB/updateLotComment.js new file mode 100644 index 00000000..56f5de01 --- /dev/null +++ b/helpers/lotOccupancyDB/updateLotComment.js @@ -0,0 +1,20 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import { dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; +export const updateLotComment = (commentForm, requestSession) => { + const rightNowMillis = Date.now(); + const database = sqlite(databasePath); + const result = database + .prepare("update LotComments" + + " set lotCommentDate = ?," + + " lotCommentTime = ?," + + " lotComment = ?," + + " recordUpdate_userName = ?," + + " recordUpdate_timeMillis = ?" + + " where recordDelete_timeMillis is null" + + " and lotCommentId = ?") + .run(dateStringToInteger(commentForm.lotCommentDateString), dateStringToInteger(commentForm.lotCommentTimeString), commentForm.lotComment, requestSession.user.userName, rightNowMillis, commentForm.lotCommentId); + database.close(); + return result.changes > 0; +}; +export default updateLotComment; diff --git a/helpers/lotOccupancyDB/updateLotComment.ts b/helpers/lotOccupancyDB/updateLotComment.ts new file mode 100644 index 00000000..7a4cd6d9 --- /dev/null +++ b/helpers/lotOccupancyDB/updateLotComment.ts @@ -0,0 +1,51 @@ +import sqlite from "better-sqlite3"; + +import { + lotOccupancyDB as databasePath +} from "../../data/databasePaths.js"; + +import { + dateStringToInteger +} from "@cityssm/expressjs-server-js/dateTimeFns.js"; + +import type * as recordTypes from "../../types/recordTypes"; + + +interface UpdateLotCommentForm { + lotCommentId: string | number; + lotCommentDateString: string; + lotCommentTimeString: string; + lotComment: string; +} + + +export const updateLotComment = + (commentForm: UpdateLotCommentForm, requestSession: recordTypes.PartialSession): boolean => { + + const rightNowMillis = Date.now(); + + const database = sqlite(databasePath); + + const result = database + .prepare("update LotComments" + + " set lotCommentDate = ?," + + " lotCommentTime = ?," + + " lotComment = ?," + + " recordUpdate_userName = ?," + + " recordUpdate_timeMillis = ?" + + " where recordDelete_timeMillis is null" + + " and lotCommentId = ?") + .run(dateStringToInteger(commentForm.lotCommentDateString), + dateStringToInteger(commentForm.lotCommentTimeString), + commentForm.lotComment, + requestSession.user.userName, + rightNowMillis, + commentForm.lotCommentId); + + database.close(); + + return result.changes > 0; + }; + + +export default updateLotComment; \ No newline at end of file diff --git a/public-typescript/lotEdit.js b/public-typescript/lotEdit.js index 631bedbe..ce11f30f 100644 --- a/public-typescript/lotEdit.js +++ b/public-typescript/lotEdit.js @@ -32,13 +32,124 @@ Object.defineProperty(exports, "__esModule", { value: true }); formElement.addEventListener("submit", updateLot); los.initializeUnlockFieldButtons(formElement); let lotComments = exports.lotComments; + const openEditLotComment = (clickEvent) => { + const lotCommentId = Number.parseInt(clickEvent.currentTarget.closest("tr").dataset.lotCommentId, 10); + const lotComment = lotComments.find((currentLotComment) => { + return currentLotComment.lotCommentId === lotCommentId; + }); + let editFormElement; + let editCloseModalFunction; + const editComment = (submitEvent) => { + submitEvent.preventDefault(); + cityssm.postJSON(urlPrefix + "/lots/doUpdateLotComment", editFormElement, (responseJSON) => { + if (responseJSON.success) { + lotComments = responseJSON.lotComments; + editCloseModalFunction(); + renderLotComments(); + } + else { + bulmaJS.alert({ + title: "Error Updating Comment", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + cityssm.openHtmlModal("lot-editComment", { + onshow: (modalElement) => { + los.populateAliases(modalElement); + modalElement.querySelector("#lotCommentEdit--lotId").value = lotId; + modalElement.querySelector("#lotCommentEdit--lotCommentId").value = lotCommentId.toString(); + modalElement.querySelector("#lotCommentEdit--lotComment").value = lotComment.lotComment; + modalElement.querySelector("#lotCommentEdit--lotCommentDateString").value = lotComment.lotCommentDateString; + modalElement.querySelector("#lotCommentEdit--lotCommentTimeString").value = lotComment.lotCommentTimeString; + }, + onshown: (modalElement, closeModalFunction) => { + bulmaJS.toggleHtmlClipped(); + modalElement.querySelector("#lotCommentEdit--lotComment").focus(); + editFormElement = modalElement.querySelector("form"); + editFormElement.addEventListener("submit", editComment); + editCloseModalFunction = closeModalFunction; + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + } + }); + }; + const deleteLotComment = (clickEvent) => { + const lotCommentId = Number.parseInt(clickEvent.currentTarget.closest("tr").dataset.lotCommentId, 10); + const doDelete = () => { + cityssm.postJSON(urlPrefix + "/lots/doDeleteLotComment", { + lotId, + lotCommentId + }, (responseJSON) => { + if (responseJSON.success) { + lotComments = responseJSON.lotComments; + renderLotComments(); + } + else { + bulmaJS.alert({ + title: "Error Removing Comment", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + bulmaJS.confirm({ + title: "Remove Comment?", + message: "Are you sure you want to remove this comment?", + okButton: { + text: "Yes, Remove Comment", + callbackFunction: doDelete + }, + contextualColorName: "warning" + }); + }; const renderLotComments = () => { - const lotCommentsContainerElement = document.querySelector("#container--lotComments"); + const containerElement = document.querySelector("#container--lotComments"); if (lotComments.length === 0) { - lotCommentsContainerElement.innerHTML = "
+<% if (lot.lotComments.length > 0) { %> +| Commentor | +Comment Date | +Comment | +
|---|---|---|
| <%= lotComment.recordCreate_userName %> | ++ <%= lotComment.lotCommentDateString %> + <%= (lotComment.lotCommentTime === 0 ? "" : lotComment.lotCommentTimeString) %> + | +<%= lotComment.lotComment %> | +