diff --git a/handlers/workOrders-post/doAddWorkOrderComment.d.ts b/handlers/workOrders-post/doAddWorkOrderComment.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/workOrders-post/doAddWorkOrderComment.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/workOrders-post/doAddWorkOrderComment.js b/handlers/workOrders-post/doAddWorkOrderComment.js new file mode 100644 index 00000000..12d77ef5 --- /dev/null +++ b/handlers/workOrders-post/doAddWorkOrderComment.js @@ -0,0 +1,11 @@ +import { addWorkOrderComment } from "../../helpers/lotOccupancyDB/addWorkOrderComment.js"; +import { getWorkOrderComments } from "../../helpers/lotOccupancyDB/getWorkOrderComments.js"; +export const handler = async (request, response) => { + addWorkOrderComment(request.body, request.session); + const workOrderComments = getWorkOrderComments(request.body.workOrderId); + response.json({ + success: true, + workOrderComments + }); +}; +export default handler; diff --git a/handlers/workOrders-post/doAddWorkOrderComment.ts b/handlers/workOrders-post/doAddWorkOrderComment.ts new file mode 100644 index 00000000..d0d65cf9 --- /dev/null +++ b/handlers/workOrders-post/doAddWorkOrderComment.ts @@ -0,0 +1,18 @@ +import type { RequestHandler } from "express"; + +import { addWorkOrderComment } from "../../helpers/lotOccupancyDB/addWorkOrderComment.js"; + +import { getWorkOrderComments } from "../../helpers/lotOccupancyDB/getWorkOrderComments.js"; + +export const handler: RequestHandler = async (request, response) => { + addWorkOrderComment(request.body, request.session); + + const workOrderComments = getWorkOrderComments(request.body.workOrderId); + + response.json({ + success: true, + workOrderComments + }); +}; + +export default handler; diff --git a/handlers/workOrders-post/doDeleteWorkOrderComment.d.ts b/handlers/workOrders-post/doDeleteWorkOrderComment.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/workOrders-post/doDeleteWorkOrderComment.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/workOrders-post/doDeleteWorkOrderComment.js b/handlers/workOrders-post/doDeleteWorkOrderComment.js new file mode 100644 index 00000000..2765358c --- /dev/null +++ b/handlers/workOrders-post/doDeleteWorkOrderComment.js @@ -0,0 +1,11 @@ +import { deleteWorkOrderComment } from "../../helpers/lotOccupancyDB/deleteWorkOrderComment.js"; +import { getWorkOrderComments } from "../../helpers/lotOccupancyDB/getWorkOrderComments.js"; +export const handler = async (request, response) => { + const success = deleteWorkOrderComment(request.body.workOrderCommentId, request.session); + const workOrderComments = getWorkOrderComments(request.body.workOrderId); + response.json({ + success, + workOrderComments + }); +}; +export default handler; diff --git a/handlers/workOrders-post/doDeleteWorkOrderComment.ts b/handlers/workOrders-post/doDeleteWorkOrderComment.ts new file mode 100644 index 00000000..2b7a7cb8 --- /dev/null +++ b/handlers/workOrders-post/doDeleteWorkOrderComment.ts @@ -0,0 +1,18 @@ +import type { RequestHandler } from "express"; + +import { deleteWorkOrderComment } from "../../helpers/lotOccupancyDB/deleteWorkOrderComment.js"; + +import { getWorkOrderComments } from "../../helpers/lotOccupancyDB/getWorkOrderComments.js"; + +export const handler: RequestHandler = async (request, response) => { + const success = deleteWorkOrderComment(request.body.workOrderCommentId, request.session); + + const workOrderComments = getWorkOrderComments(request.body.workOrderId); + + response.json({ + success, + workOrderComments + }); +}; + +export default handler; diff --git a/handlers/workOrders-post/doUpdateWorkOrderComment.d.ts b/handlers/workOrders-post/doUpdateWorkOrderComment.d.ts new file mode 100644 index 00000000..9621c611 --- /dev/null +++ b/handlers/workOrders-post/doUpdateWorkOrderComment.d.ts @@ -0,0 +1,3 @@ +import type { RequestHandler } from "express"; +export declare const handler: RequestHandler; +export default handler; diff --git a/handlers/workOrders-post/doUpdateWorkOrderComment.js b/handlers/workOrders-post/doUpdateWorkOrderComment.js new file mode 100644 index 00000000..838e43fb --- /dev/null +++ b/handlers/workOrders-post/doUpdateWorkOrderComment.js @@ -0,0 +1,11 @@ +import { updateWorkOrderComment } from "../../helpers/lotOccupancyDB/updateWorkOrderComment.js"; +import { getWorkOrderComments } from "../../helpers/lotOccupancyDB/getWorkOrderComments.js"; +export const handler = async (request, response) => { + const success = updateWorkOrderComment(request.body, request.session); + const workOrderComments = getWorkOrderComments(request.body.workOrderId); + response.json({ + success, + workOrderComments + }); +}; +export default handler; diff --git a/handlers/workOrders-post/doUpdateWorkOrderComment.ts b/handlers/workOrders-post/doUpdateWorkOrderComment.ts new file mode 100644 index 00000000..6f088248 --- /dev/null +++ b/handlers/workOrders-post/doUpdateWorkOrderComment.ts @@ -0,0 +1,18 @@ +import type { RequestHandler } from "express"; + +import { updateWorkOrderComment } from "../../helpers/lotOccupancyDB/updateWorkOrderComment.js"; + +import { getWorkOrderComments } from "../../helpers/lotOccupancyDB/getWorkOrderComments.js"; + +export const handler: RequestHandler = async (request, response) => { + const success = updateWorkOrderComment(request.body, request.session); + + const workOrderComments = getWorkOrderComments(request.body.workOrderId); + + response.json({ + success, + workOrderComments + }); +}; + +export default handler; diff --git a/helpers/lotOccupancyDB/addWorkOrderComment.d.ts b/helpers/lotOccupancyDB/addWorkOrderComment.d.ts new file mode 100644 index 00000000..2712f560 --- /dev/null +++ b/helpers/lotOccupancyDB/addWorkOrderComment.d.ts @@ -0,0 +1,7 @@ +import type * as recordTypes from "../../types/recordTypes"; +interface AddWorkOrderCommentForm { + workOrderId: string; + workOrderComment: string; +} +export declare const addWorkOrderComment: (workOrderCommentForm: AddWorkOrderCommentForm, requestSession: recordTypes.PartialSession) => number; +export default addWorkOrderComment; diff --git a/helpers/lotOccupancyDB/addWorkOrderComment.js b/helpers/lotOccupancyDB/addWorkOrderComment.js new file mode 100644 index 00000000..7cbb433c --- /dev/null +++ b/helpers/lotOccupancyDB/addWorkOrderComment.js @@ -0,0 +1,17 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +import * as dateTimeFunctions from "@cityssm/expressjs-server-js/dateTimeFns.js"; +export const addWorkOrderComment = (workOrderCommentForm, requestSession) => { + const database = sqlite(databasePath); + const rightNow = new Date(); + const result = database + .prepare("insert into WorkOrderComments (" + + "workOrderId, workOrderCommentDate, workOrderCommentTime, workOrderComment," + + " recordCreate_userName, recordCreate_timeMillis," + + " recordUpdate_userName, recordUpdate_timeMillis)" + + " values (?, ?, ?, ?, ?, ?, ?, ?)") + .run(workOrderCommentForm.workOrderId, dateTimeFunctions.dateToInteger(rightNow), dateTimeFunctions.dateToTimeInteger(rightNow), workOrderCommentForm.workOrderComment, requestSession.user.userName, rightNow.getTime(), requestSession.user.userName, rightNow.getTime()); + database.close(); + return result.lastInsertRowid; +}; +export default addWorkOrderComment; diff --git a/helpers/lotOccupancyDB/addWorkOrderComment.ts b/helpers/lotOccupancyDB/addWorkOrderComment.ts new file mode 100644 index 00000000..2db4214d --- /dev/null +++ b/helpers/lotOccupancyDB/addWorkOrderComment.ts @@ -0,0 +1,46 @@ +import sqlite from "better-sqlite3"; + +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; + +import * as dateTimeFunctions from "@cityssm/expressjs-server-js/dateTimeFns.js"; + +import type * as recordTypes from "../../types/recordTypes"; + +interface AddWorkOrderCommentForm { + workOrderId: string; + workOrderComment: string; +} + +export const addWorkOrderComment = ( + workOrderCommentForm: AddWorkOrderCommentForm, + requestSession: recordTypes.PartialSession +): number => { + const database = sqlite(databasePath); + + const rightNow = new Date(); + + const result = database + .prepare( + "insert into WorkOrderComments (" + + "workOrderId, workOrderCommentDate, workOrderCommentTime, workOrderComment," + + " recordCreate_userName, recordCreate_timeMillis," + + " recordUpdate_userName, recordUpdate_timeMillis)" + + " values (?, ?, ?, ?, ?, ?, ?, ?)" + ) + .run( + workOrderCommentForm.workOrderId, + dateTimeFunctions.dateToInteger(rightNow), + dateTimeFunctions.dateToTimeInteger(rightNow), + workOrderCommentForm.workOrderComment, + requestSession.user.userName, + rightNow.getTime(), + requestSession.user.userName, + rightNow.getTime() + ); + + database.close(); + + return result.lastInsertRowid as number; +}; + +export default addWorkOrderComment; diff --git a/helpers/lotOccupancyDB/deleteWorkOrderComment.d.ts b/helpers/lotOccupancyDB/deleteWorkOrderComment.d.ts new file mode 100644 index 00000000..ce8e38e0 --- /dev/null +++ b/helpers/lotOccupancyDB/deleteWorkOrderComment.d.ts @@ -0,0 +1,3 @@ +import type * as recordTypes from "../../types/recordTypes"; +export declare const deleteWorkOrderComment: (workOrderCommentId: number | string, requestSession: recordTypes.PartialSession) => boolean; +export default deleteWorkOrderComment; diff --git a/helpers/lotOccupancyDB/deleteWorkOrderComment.js b/helpers/lotOccupancyDB/deleteWorkOrderComment.js new file mode 100644 index 00000000..c14aef38 --- /dev/null +++ b/helpers/lotOccupancyDB/deleteWorkOrderComment.js @@ -0,0 +1,15 @@ +import sqlite from "better-sqlite3"; +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; +export const deleteWorkOrderComment = (workOrderCommentId, requestSession) => { + const database = sqlite(databasePath); + const rightNowMillis = Date.now(); + const result = database + .prepare("update WorkOrderComments" + + " set recordDelete_userName = ?," + + " recordDelete_timeMillis = ?" + + " where workOrderCommentId = ?") + .run(requestSession.user.userName, rightNowMillis, workOrderCommentId); + database.close(); + return result.changes > 0; +}; +export default deleteWorkOrderComment; diff --git a/helpers/lotOccupancyDB/deleteWorkOrderComment.ts b/helpers/lotOccupancyDB/deleteWorkOrderComment.ts new file mode 100644 index 00000000..da03ce09 --- /dev/null +++ b/helpers/lotOccupancyDB/deleteWorkOrderComment.ts @@ -0,0 +1,29 @@ +import sqlite from "better-sqlite3"; + +import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; + +import type * as recordTypes from "../../types/recordTypes"; + +export const deleteWorkOrderComment = ( + workOrderCommentId: number | string, + requestSession: recordTypes.PartialSession +): boolean => { + const database = sqlite(databasePath); + + const rightNowMillis = Date.now(); + + const result = database + .prepare( + "update WorkOrderComments" + + " set recordDelete_userName = ?," + + " recordDelete_timeMillis = ?" + + " where workOrderCommentId = ?" + ) + .run(requestSession.user.userName, rightNowMillis, workOrderCommentId); + + database.close(); + + return result.changes > 0; +}; + +export default deleteWorkOrderComment; diff --git a/helpers/lotOccupancyDB/updateWorkOrderComment.d.ts b/helpers/lotOccupancyDB/updateWorkOrderComment.d.ts new file mode 100644 index 00000000..743edf8b --- /dev/null +++ b/helpers/lotOccupancyDB/updateWorkOrderComment.d.ts @@ -0,0 +1,9 @@ +import type * as recordTypes from "../../types/recordTypes"; +interface UpdateWorkOrderCommentForm { + workOrderCommentId: string | number; + workOrderCommentDateString: string; + workOrderCommentTimeString: string; + workOrderComment: string; +} +export declare const updateWorkOrderComment: (commentForm: UpdateWorkOrderCommentForm, requestSession: recordTypes.PartialSession) => boolean; +export default updateWorkOrderComment; diff --git a/helpers/lotOccupancyDB/updateWorkOrderComment.js b/helpers/lotOccupancyDB/updateWorkOrderComment.js new file mode 100644 index 00000000..419a41a8 --- /dev/null +++ b/helpers/lotOccupancyDB/updateWorkOrderComment.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 updateWorkOrderComment = (commentForm, requestSession) => { + const rightNowMillis = Date.now(); + const database = sqlite(databasePath); + const result = database + .prepare("update WorkOrderComments" + + " set workOrderCommentDate = ?," + + " workOrderCommentTime = ?," + + " workOrderComment = ?," + + " recordUpdate_userName = ?," + + " recordUpdate_timeMillis = ?" + + " where recordDelete_timeMillis is null" + + " and workOrderCommentId = ?") + .run(dateStringToInteger(commentForm.workOrderCommentDateString), dateStringToInteger(commentForm.workOrderCommentTimeString), commentForm.workOrderComment, requestSession.user.userName, rightNowMillis, commentForm.workOrderCommentId); + database.close(); + return result.changes > 0; +}; +export default updateWorkOrderComment; diff --git a/helpers/lotOccupancyDB/updateWorkOrderComment.ts b/helpers/lotOccupancyDB/updateWorkOrderComment.ts new file mode 100644 index 00000000..e6584ac6 --- /dev/null +++ b/helpers/lotOccupancyDB/updateWorkOrderComment.ts @@ -0,0 +1,49 @@ +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 UpdateWorkOrderCommentForm { + workOrderCommentId: string | number; + workOrderCommentDateString: string; + workOrderCommentTimeString: string; + workOrderComment: string; +} + +export const updateWorkOrderComment = ( + commentForm: UpdateWorkOrderCommentForm, + requestSession: recordTypes.PartialSession +): boolean => { + const rightNowMillis = Date.now(); + + const database = sqlite(databasePath); + + const result = database + .prepare( + "update WorkOrderComments" + + " set workOrderCommentDate = ?," + + " workOrderCommentTime = ?," + + " workOrderComment = ?," + + " recordUpdate_userName = ?," + + " recordUpdate_timeMillis = ?" + + " where recordDelete_timeMillis is null" + + " and workOrderCommentId = ?" + ) + .run( + dateStringToInteger(commentForm.workOrderCommentDateString), + dateStringToInteger(commentForm.workOrderCommentTimeString), + commentForm.workOrderComment, + requestSession.user.userName, + rightNowMillis, + commentForm.workOrderCommentId + ); + + database.close(); + + return result.changes > 0; +}; + +export default updateWorkOrderComment; diff --git a/public-typescript/workOrderEdit.js b/public-typescript/workOrderEdit.js index 52f6aa43..bfe45f45 100644 --- a/public-typescript/workOrderEdit.js +++ b/public-typescript/workOrderEdit.js @@ -3,24 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true }); (() => { const los = exports.los; const urlPrefix = document.querySelector("main").dataset.urlPrefix; - const workOrderId = document.querySelector("#workOrderEdit--workOrderId").value; + const workOrderId = document.querySelector("#workOrderEdit--workOrderId") + .value; const isCreate = workOrderId === ""; const workOrderFormElement = document.querySelector("#form--workOrderEdit"); - los.initializeDatePickers(workOrderFormElement.querySelector("#workOrderEdit--workOrderOpenDateString").closest(".field")); + los.initializeDatePickers(workOrderFormElement + .querySelector("#workOrderEdit--workOrderOpenDateString") + .closest(".field")); los.initializeUnlockFieldButtons(workOrderFormElement); - workOrderFormElement - .addEventListener("submit", (submitEvent) => { + workOrderFormElement.addEventListener("submit", (submitEvent) => { submitEvent.preventDefault(); - cityssm.postJSON(urlPrefix + - "/workOrders/" + - (isCreate ? "doCreateWorkOrder" : "doUpdateWorkOrder"), submitEvent.currentTarget, (responseJSON) => { + cityssm.postJSON(urlPrefix + "/workOrders/" + (isCreate ? "doCreateWorkOrder" : "doUpdateWorkOrder"), submitEvent.currentTarget, (responseJSON) => { if (responseJSON.success) { if (isCreate) { window.location.href = - urlPrefix + - "/workOrders/" + - responseJSON.workOrderId + - "/edit"; + urlPrefix + "/workOrders/" + responseJSON.workOrderId + "/edit"; } else { bulmaJS.alert({ @@ -45,8 +42,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); workOrderId }, (responseJSON) => { if (responseJSON.success) { - window.location.href = - urlPrefix + "/workOrders/" + workOrderId; + window.location.href = urlPrefix + "/workOrders/" + workOrderId; } else { bulmaJS.alert({ @@ -57,9 +53,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); } }); }; - document - .querySelector("#button--closeWorkOrder") - .addEventListener("click", () => { + document.querySelector("#button--closeWorkOrder").addEventListener("click", () => { const hasOpenMilestones = workOrderMilestones.some((milestone) => { return !milestone.workOrderMilestoneCompletionDate; }); @@ -130,8 +124,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); lotOccupancyId }, (responseJSON) => { if (responseJSON.success) { - workOrderLotOccupancies = - responseJSON.workOrderLotOccupancies; + workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; renderRelatedLotsAndOccupancies(); } else { @@ -188,8 +181,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); lotOccupancyId }, (responseJSON) => { if (responseJSON.success) { - workOrderLotOccupancies = - responseJSON.workOrderLotOccupancies; + workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; renderRelatedLotsAndOccupancies(); } else { @@ -205,13 +197,13 @@ Object.defineProperty(exports, "__esModule", { value: true }); }); }; const addLotFromLotOccupancy = (clickEvent) => { - const lotId = clickEvent.currentTarget.dataset - .lotId; + const lotId = clickEvent.currentTarget.dataset.lotId; addLot(lotId); }; const renderRelatedOccupancies = () => { const occupanciesContainerElement = document.querySelector("#container--lotOccupancies"); - document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent = workOrderLotOccupancies.length.toString(); + document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent = + workOrderLotOccupancies.length.toString(); if (workOrderLotOccupancies.length === 0) { occupanciesContainerElement.innerHTML = '
' + @@ -240,8 +232,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); for (const lotOccupancy of workOrderLotOccupancies) { const rowElement = document.createElement("tr"); rowElement.className = "container--lotOccupancy"; - rowElement.dataset.lotOccupancyId = - lotOccupancy.lotOccupancyId.toString(); + rowElement.dataset.lotOccupancyId = lotOccupancy.lotOccupancyId.toString(); const isActive = !(lotOccupancy.occupancyEndDate && lotOccupancy.occupancyEndDateString < currentDateString); const hasLotRecord = lotOccupancy.lotId && @@ -306,13 +297,9 @@ Object.defineProperty(exports, "__esModule", { value: true }); ? '(No ' + cityssm.escapeHTML(exports.aliases.occupants) + ")" - : cityssm.escapeHTML(lotOccupancy.lotOccupancyOccupants[0] - .occupantName) + + : cityssm.escapeHTML(lotOccupancy.lotOccupancyOccupants[0].occupantName) + (lotOccupancy.lotOccupancyOccupants.length > 1 - ? " plus " + - (lotOccupancy.lotOccupancyOccupants - .length - - 1) + ? " plus " + (lotOccupancy.lotOccupancyOccupants.length - 1) : "")) + "") + ("" + @@ -328,9 +315,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); rowElement .querySelector(".button--deleteLotOccupancy") .addEventListener("click", deleteLotOccupancy); - occupanciesContainerElement - .querySelector("tbody") - .append(rowElement); + occupanciesContainerElement.querySelector("tbody").append(rowElement); } }; const deleteLot = (clickEvent) => { @@ -373,7 +358,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); }; const renderRelatedLots = () => { const lotsContainerElement = document.querySelector("#container--lots"); - document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent = workOrderLots.length.toString(); + document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent = + workOrderLots.length.toString(); if (workOrderLots.length === 0) { lotsContainerElement.innerHTML = '
' + @@ -418,9 +404,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); '' + "" + ""); - rowElement - .querySelector(".button--deleteLot") - .addEventListener("click", deleteLot); + rowElement.querySelector(".button--deleteLot").addEventListener("click", deleteLot); lotsContainerElement.querySelector("tbody").append(rowElement); } }; @@ -429,9 +413,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); renderRelatedLots(); }; renderRelatedLotsAndOccupancies(); - document - .querySelector("#button--addLotOccupancy") - .addEventListener("click", () => { + document.querySelector("#button--addLotOccupancy").addEventListener("click", () => { let searchFormElement; let searchResultsContainerElement; const doAddLotOccupancy = (clickEvent) => { @@ -465,9 +447,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); "" + "" + '' + - ("" + - exports.aliases.occupancy + - " Type") + + ("" + exports.aliases.occupancy + " Type") + ("" + exports.aliases.lot + "") + "Start Date" + "End Date" + @@ -478,8 +458,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); ""; for (const lotOccupancy of responseJSON.lotOccupancies) { const rowElement = document.createElement("tr"); - rowElement.className = - "container--lotOccupancy"; + rowElement.className = "container--lotOccupancy"; rowElement.dataset.lotOccupancyId = lotOccupancy.lotOccupancyId.toString(); rowElement.innerHTML = @@ -492,9 +471,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); cityssm.escapeHTML(lotOccupancy.occupancyType) + ""); if (lotOccupancy.lotId) { - rowElement.insertAdjacentHTML("beforeend", "" + - cityssm.escapeHTML(lotOccupancy.lotName) + - ""); + rowElement.insertAdjacentHTML("beforeend", "" + cityssm.escapeHTML(lotOccupancy.lotName) + ""); } else { rowElement.insertAdjacentHTML("beforeend", "" + @@ -512,30 +489,20 @@ Object.defineProperty(exports, "__esModule", { value: true }); : '(No End Date)') + "") + ("" + - (lotOccupancy.lotOccupancyOccupants - .length === 0 + (lotOccupancy.lotOccupancyOccupants.length === 0 ? '(No ' + cityssm.escapeHTML(exports.aliases.occupants) + ")" - : cityssm.escapeHTML(lotOccupancy - .lotOccupancyOccupants[0] - .occupantName) + - (lotOccupancy - .lotOccupancyOccupants - .length > 1 + : cityssm.escapeHTML(lotOccupancy.lotOccupancyOccupants[0].occupantName) + + (lotOccupancy.lotOccupancyOccupants.length > 1 ? " plus " + - (lotOccupancy - .lotOccupancyOccupants - .length - - 1) + (lotOccupancy.lotOccupancyOccupants.length - 1) : "")) + "")); rowElement .querySelector(".button--addLotOccupancy") .addEventListener("click", doAddLotOccupancy); - searchResultsContainerElement - .querySelector("tbody") - .append(rowElement); + searchResultsContainerElement.querySelector("tbody").append(rowElement); } }); }; @@ -543,8 +510,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); onshow: (modalElement) => { los.populateAliases(modalElement); searchFormElement = modalElement.querySelector("form"); - searchResultsContainerElement = - modalElement.querySelector("#resultsContainer--lotOccupancyAdd"); + searchResultsContainerElement = modalElement.querySelector("#resultsContainer--lotOccupancyAdd"); modalElement.querySelector("#lotOccupancySearch--notWorkOrderId").value = workOrderId; modalElement.querySelector("#lotOccupancySearch--occupancyEffectiveDateString").value = document.querySelector("#workOrderEdit--workOrderOpenDateString").value; doSearch(); @@ -564,9 +530,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); } }); }); - document - .querySelector("#button--addLot") - .addEventListener("click", () => { + document.querySelector("#button--addLot").addEventListener("click", () => { let searchFormElement; let searchResultsContainerElement; const doAddLot = (clickEvent) => { @@ -624,18 +588,12 @@ Object.defineProperty(exports, "__esModule", { value: true }); "" + cityssm.escapeHTML(lot.mapName) + "" + - ("" + - cityssm.escapeHTML(lot.lotType) + - "") + - ("" + - cityssm.escapeHTML(lot.lotStatus) + - ""); + ("" + cityssm.escapeHTML(lot.lotType) + "") + + ("" + cityssm.escapeHTML(lot.lotStatus) + ""); rowElement .querySelector(".button--addLot") .addEventListener("click", doAddLot); - searchResultsContainerElement - .querySelector("tbody") - .append(rowElement); + searchResultsContainerElement.querySelector("tbody").append(rowElement); } }); }; @@ -643,14 +601,12 @@ Object.defineProperty(exports, "__esModule", { value: true }); onshow: (modalElement) => { los.populateAliases(modalElement); searchFormElement = modalElement.querySelector("form"); - searchResultsContainerElement = - modalElement.querySelector("#resultsContainer--lotAdd"); + searchResultsContainerElement = modalElement.querySelector("#resultsContainer--lotAdd"); modalElement.querySelector("#lotSearch--notWorkOrderId").value = workOrderId; const lotStatusElement = modalElement.querySelector("#lotSearch--lotStatusId"); for (const lotStatus of exports.lotStatuses) { const optionElement = document.createElement("option"); - optionElement.value = - lotStatus.lotStatusId.toString(); + optionElement.value = lotStatus.lotStatusId.toString(); optionElement.textContent = lotStatus.lotStatus; lotStatusElement.append(optionElement); } @@ -672,9 +628,177 @@ Object.defineProperty(exports, "__esModule", { value: true }); }); }); } + let workOrderComments = exports.workOrderComments; + delete exports.workOrderComments; + const openEditWorkOrderComment = (clickEvent) => { + const workOrderCommentId = Number.parseInt(clickEvent.currentTarget.closest("tr").dataset.workOrderCommentId, 10); + const workOrderComment = workOrderComments.find((currentComment) => { + return currentComment.workOrderCommentId === workOrderCommentId; + }); + console.log(workOrderComments); + let editFormElement; + let editCloseModalFunction; + const editComment = (submitEvent) => { + submitEvent.preventDefault(); + cityssm.postJSON(urlPrefix + "/workOrders/doUpdateWorkOrderComment", editFormElement, (responseJSON) => { + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments; + editCloseModalFunction(); + renderWorkOrderComments(); + } + else { + bulmaJS.alert({ + title: "Error Updating Comment", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + }); + }; + cityssm.openHtmlModal("workOrder-editComment", { + onshow: (modalElement) => { + modalElement.querySelector("#workOrderCommentEdit--workOrderId").value = workOrderId; + modalElement.querySelector("#workOrderCommentEdit--workOrderCommentId").value = workOrderCommentId.toString(); + modalElement.querySelector("#workOrderCommentEdit--workOrderComment").value = workOrderComment.workOrderComment; + modalElement.querySelector("#workOrderCommentEdit--workOrderCommentDateString").value = workOrderComment.workOrderCommentDateString; + modalElement.querySelector("#workOrderCommentEdit--workOrderCommentTimeString").value = workOrderComment.workOrderCommentTimeString; + }, + onshown: (modalElement, closeModalFunction) => { + bulmaJS.toggleHtmlClipped(); + los.initializeDatePickers(modalElement); + los.initializeTimePickers(modalElement); + modalElement.querySelector("#workOrderCommentEdit--workOrderComment").focus(); + editFormElement = modalElement.querySelector("form"); + editFormElement.addEventListener("submit", editComment); + editCloseModalFunction = closeModalFunction; + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + } + }); + }; + const deleteWorkOrderComment = (clickEvent) => { + const workOrderCommentId = Number.parseInt(clickEvent.currentTarget.closest("tr").dataset.workOrderCommentId, 10); + const doDelete = () => { + cityssm.postJSON(urlPrefix + "/workOrders/doDeleteWorkOrderComment", { + workOrderId, + workOrderCommentId + }, (responseJSON) => { + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments; + renderWorkOrderComments(); + } + 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 renderWorkOrderComments = () => { + const containerElement = document.querySelector("#container--workOrderComments"); + if (workOrderComments.length === 0) { + containerElement.innerHTML = + '
' + + '

There are no comments to display.

' + + "
"; + return; + } + const tableElement = document.createElement("table"); + tableElement.className = "table is-fullwidth is-striped is-hoverable"; + tableElement.innerHTML = + "" + + "Commentor" + + "Comment Date" + + "Comment" + + 'Options' + + "" + + ""; + for (const workOrderComment of workOrderComments) { + const tableRowElement = document.createElement("tr"); + tableRowElement.dataset.workOrderCommentId = workOrderComment.workOrderCommentId.toString(); + tableRowElement.innerHTML = + "" + + cityssm.escapeHTML(workOrderComment.recordCreate_userName) + + "" + + "" + + workOrderComment.workOrderCommentDateString + + (workOrderComment.workOrderCommentTime === 0 + ? "" + : " " + workOrderComment.workOrderCommentTimeString) + + "" + + "" + + cityssm.escapeHTML(workOrderComment.workOrderComment) + + "" + + ('' + + '
' + + ('") + + ('") + + "
" + + ""); + tableRowElement + .querySelector(".button--edit") + .addEventListener("click", openEditWorkOrderComment); + tableRowElement + .querySelector(".button--delete") + .addEventListener("click", deleteWorkOrderComment); + tableElement.querySelector("tbody").append(tableRowElement); + } + containerElement.innerHTML = ""; + containerElement.append(tableElement); + }; + const openAddCommentModal = () => { + let addCommentCloseModalFunction; + const doAddComment = (formEvent) => { + formEvent.preventDefault(); + cityssm.postJSON(urlPrefix + "/workOrders/doAddWorkOrderComment", formEvent.currentTarget, (responseJSON) => { + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments; + renderWorkOrderComments(); + addCommentCloseModalFunction(); + } + }); + }; + cityssm.openHtmlModal("workOrder-addComment", { + onshow(modalElement) { + los.populateAliases(modalElement); + modalElement.querySelector("#workOrderCommentAdd--workOrderId").value = workOrderId; + modalElement.querySelector("form").addEventListener("submit", doAddComment); + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + addCommentCloseModalFunction = closeModalFunction; + modalElement.querySelector("#workOrderCommentAdd--workOrderComment").focus(); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + document.querySelector("#workOrderComments--add").focus(); + } + }); + }; if (!isCreate) { - workOrderMilestones = - exports.workOrderMilestones; + document.querySelector("#workOrderComments--add").addEventListener("click", openAddCommentModal); + renderWorkOrderComments(); + } + if (!isCreate) { + workOrderMilestones = exports.workOrderMilestones; delete exports.workOrderMilestones; const processMilestoneResponse = (responseJSON) => { if (responseJSON.success) { @@ -694,8 +818,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const currentDateString = cityssm.dateToString(new Date()); const workOrderMilestoneId = Number.parseInt(clickEvent.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId, 10); const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { - return (currentMilestone.workOrderMilestoneId === - workOrderMilestoneId); + return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; }); const doComplete = () => { cityssm.postJSON(urlPrefix + "/workOrders/doCompleteWorkOrderMilestone", { @@ -706,8 +829,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); bulmaJS.confirm({ title: "Complete Milestone", message: "Are you sure you want to complete this milestone?" + - (workOrderMilestone.workOrderMilestoneDateString > - currentDateString + (workOrderMilestone.workOrderMilestoneDateString > currentDateString ? "
Note that this milestone is expected to be completed in the future." : ""), messageIsHtml: true, @@ -760,8 +882,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); clickEvent.preventDefault(); const workOrderMilestoneId = Number.parseInt(clickEvent.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId, 10); const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { - return (currentMilestone.workOrderMilestoneId === - workOrderMilestoneId); + return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; }); let editCloseModalFunction; const doEdit = (submitEvent) => { @@ -776,16 +897,13 @@ Object.defineProperty(exports, "__esModule", { value: true }); cityssm.openHtmlModal("workOrder-editMilestone", { onshow: (modalElement) => { modalElement.querySelector("#milestoneEdit--workOrderId").value = workOrderId; - modalElement.querySelector("#milestoneEdit--workOrderMilestoneId").value = - workOrderMilestone.workOrderMilestoneId.toString(); + modalElement.querySelector("#milestoneEdit--workOrderMilestoneId").value = workOrderMilestone.workOrderMilestoneId.toString(); const milestoneTypeElement = modalElement.querySelector("#milestoneEdit--workOrderMilestoneTypeId"); let milestoneTypeFound = false; for (const milestoneType of exports.workOrderMilestoneTypes) { const optionElement = document.createElement("option"); - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString(); - optionElement.textContent = - milestoneType.workOrderMilestoneType; + optionElement.value = milestoneType.workOrderMilestoneTypeId.toString(); + optionElement.textContent = milestoneType.workOrderMilestoneType; if (milestoneType.workOrderMilestoneTypeId === workOrderMilestone.workOrderMilestoneTypeId) { optionElement.selected = true; @@ -793,20 +911,17 @@ Object.defineProperty(exports, "__esModule", { value: true }); } milestoneTypeElement.append(optionElement); } - if (!milestoneTypeFound && - workOrderMilestone.workOrderMilestoneTypeId) { + if (!milestoneTypeFound && workOrderMilestone.workOrderMilestoneTypeId) { const optionElement = document.createElement("option"); optionElement.value = workOrderMilestone.workOrderMilestoneTypeId.toString(); - optionElement.textContent = - workOrderMilestone.workOrderMilestoneType; + optionElement.textContent = workOrderMilestone.workOrderMilestoneType; optionElement.selected = true; milestoneTypeElement.append(optionElement); } modalElement.querySelector("#milestoneEdit--workOrderMilestoneDateString").value = workOrderMilestone.workOrderMilestoneDateString; if (workOrderMilestone.workOrderMilestoneTime) { - modalElement.querySelector("#milestoneEdit--workOrderMilestoneTimeString").value = - workOrderMilestone.workOrderMilestoneTimeString; + modalElement.querySelector("#milestoneEdit--workOrderMilestoneTimeString").value = workOrderMilestone.workOrderMilestoneTimeString; } modalElement.querySelector("#milestoneEdit--workOrderMilestoneDescription").value = workOrderMilestone.workOrderMilestoneDescription; }, @@ -815,9 +930,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); bulmaJS.toggleHtmlClipped(); los.initializeDatePickers(modalElement); los.initializeTimePickers(modalElement); - modalElement - .querySelector("form") - .addEventListener("submit", doEdit); + modalElement.querySelector("form").addEventListener("submit", doEdit); }, onremoved: () => { bulmaJS.toggleHtmlClipped(); @@ -832,8 +945,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); } for (const milestone of workOrderMilestones) { const panelBlockElement = document.createElement("div"); - panelBlockElement.className = - "panel-block is-block container--milestone"; + panelBlockElement.className = "panel-block is-block container--milestone"; panelBlockElement.dataset.workOrderMilestoneId = milestone.workOrderMilestoneId.toString(); panelBlockElement.innerHTML = @@ -915,9 +1027,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); bulmaJS.init(milestonesPanelElement); }; renderMilestones(); - document - .querySelector("#button--addMilestone") - .addEventListener("click", () => { + document.querySelector("#button--addMilestone").addEventListener("click", () => { let addModalElement; let addCloseModalFunction; const doAdd = (submitEvent) => { @@ -952,10 +1062,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); const milestoneTypeElement = modalElement.querySelector("#milestoneAdd--workOrderMilestoneTypeId"); for (const milestoneType of exports.workOrderMilestoneTypes) { const optionElement = document.createElement("option"); - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString(); - optionElement.textContent = - milestoneType.workOrderMilestoneType; + optionElement.value = milestoneType.workOrderMilestoneTypeId.toString(); + optionElement.textContent = milestoneType.workOrderMilestoneType; milestoneTypeElement.append(optionElement); } modalElement.querySelector("#milestoneAdd--workOrderMilestoneDateString").valueAsDate = new Date(); @@ -966,9 +1074,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); los.initializeDatePickers(modalElement); los.initializeTimePickers(modalElement); bulmaJS.toggleHtmlClipped(); - modalElement - .querySelector("form") - .addEventListener("submit", doAdd); + modalElement.querySelector("form").addEventListener("submit", doAdd); }, onremoved: () => { bulmaJS.toggleHtmlClipped(); diff --git a/public-typescript/workOrderEdit.ts b/public-typescript/workOrderEdit.ts index ca28ba87..3efe8b0c 100644 --- a/public-typescript/workOrderEdit.ts +++ b/public-typescript/workOrderEdit.ts @@ -14,56 +14,47 @@ declare const bulmaJS: BulmaJS; const urlPrefix = document.querySelector("main").dataset.urlPrefix; - const workOrderId = ( - document.querySelector( - "#workOrderEdit--workOrderId" - ) as HTMLInputElement - ).value; + const workOrderId = (document.querySelector("#workOrderEdit--workOrderId") as HTMLInputElement) + .value; const isCreate = workOrderId === ""; const workOrderFormElement = document.querySelector("#form--workOrderEdit") as HTMLFormElement; - los.initializeDatePickers(workOrderFormElement.querySelector("#workOrderEdit--workOrderOpenDateString").closest(".field")); + los.initializeDatePickers( + workOrderFormElement + .querySelector("#workOrderEdit--workOrderOpenDateString") + .closest(".field") + ); los.initializeUnlockFieldButtons(workOrderFormElement); - workOrderFormElement - .addEventListener("submit", (submitEvent) => { - submitEvent.preventDefault(); + workOrderFormElement.addEventListener("submit", (submitEvent) => { + submitEvent.preventDefault(); - cityssm.postJSON( - urlPrefix + - "/workOrders/" + - (isCreate ? "doCreateWorkOrder" : "doUpdateWorkOrder"), - submitEvent.currentTarget, - (responseJSON: { - success: boolean; - workOrderId?: number; - errorMessage?: string; - }) => { - if (responseJSON.success) { - if (isCreate) { - window.location.href = - urlPrefix + - "/workOrders/" + - responseJSON.workOrderId + - "/edit"; - } else { - bulmaJS.alert({ - message: "Work Order Updated Successfully", - contextualColorName: "success" - }); - } + cityssm.postJSON( + urlPrefix + "/workOrders/" + (isCreate ? "doCreateWorkOrder" : "doUpdateWorkOrder"), + submitEvent.currentTarget, + (responseJSON: { success: boolean; workOrderId?: number; errorMessage?: string }) => { + if (responseJSON.success) { + if (isCreate) { + window.location.href = + urlPrefix + "/workOrders/" + responseJSON.workOrderId + "/edit"; } else { bulmaJS.alert({ - title: "Error Updating Work Order", - message: responseJSON.errorMessage, - contextualColorName: "danger" + message: "Work Order Updated Successfully", + contextualColorName: "success" }); } + } else { + bulmaJS.alert({ + title: "Error Updating Work Order", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); } - ); - }); + } + ); + }); /* * Work Order Options @@ -80,8 +71,7 @@ declare const bulmaJS: BulmaJS; }, (responseJSON: { success: boolean; errorMessage?: string }) => { if (responseJSON.success) { - window.location.href = - urlPrefix + "/workOrders/" + workOrderId; + window.location.href = urlPrefix + "/workOrders/" + workOrderId; } else { bulmaJS.alert({ title: "Error Closing Work Order", @@ -93,40 +83,35 @@ declare const bulmaJS: BulmaJS; ); }; - document - .querySelector("#button--closeWorkOrder") - .addEventListener("click", () => { - const hasOpenMilestones = workOrderMilestones.some( - (milestone) => { - return !milestone.workOrderMilestoneCompletionDate; - } - ); - - if (hasOpenMilestones) { - bulmaJS.confirm({ - title: "Close Work Order with Outstanding Milestones", - message: - "Are you sure you want to close this work order with outstanding milestones?", - contextualColorName: "danger", - okButton: { - text: "Yes, Close Work Order", - callbackFunction: doClose - } - }); - } else { - bulmaJS.confirm({ - title: "Close Work Order", - message: - "Are you sure you want to close this work order?", - contextualColorName: "info", - okButton: { - text: "Yes, Close Work Order", - callbackFunction: doClose - } - }); - } + document.querySelector("#button--closeWorkOrder").addEventListener("click", () => { + const hasOpenMilestones = workOrderMilestones.some((milestone) => { + return !milestone.workOrderMilestoneCompletionDate; }); + if (hasOpenMilestones) { + bulmaJS.confirm({ + title: "Close Work Order with Outstanding Milestones", + message: + "Are you sure you want to close this work order with outstanding milestones?", + contextualColorName: "danger", + okButton: { + text: "Yes, Close Work Order", + callbackFunction: doClose + } + }); + } else { + bulmaJS.confirm({ + title: "Close Work Order", + message: "Are you sure you want to close this work order?", + contextualColorName: "info", + okButton: { + text: "Yes, Close Work Order", + callbackFunction: doClose + } + }); + } + }); + const doDelete = () => { cityssm.postJSON( urlPrefix + "/workOrders/doDeleteWorkOrder", @@ -172,8 +157,7 @@ declare const bulmaJS: BulmaJS; let workOrderLots: recordTypes.Lot[] = exports.workOrderLots; delete exports.workOrderLots; - let workOrderLotOccupancies: recordTypes.LotOccupancy[] = - exports.workOrderLotOccupancies; + let workOrderLotOccupancies: recordTypes.LotOccupancy[] = exports.workOrderLotOccupancies; delete exports.workOrderLotOccupancies; const deleteLotOccupancy = (clickEvent: Event) => { @@ -196,8 +180,7 @@ declare const bulmaJS: BulmaJS; workOrderLotOccupancies?: recordTypes.LotOccupancy[]; }) => { if (responseJSON.success) { - workOrderLotOccupancies = - responseJSON.workOrderLotOccupancies; + workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; renderRelatedLotsAndOccupancies(); } else { bulmaJS.alert({ @@ -231,10 +214,7 @@ declare const bulmaJS: BulmaJS; }); }; - const addLot = ( - lotId: number | string, - callbackFunction?: (success?: boolean) => void - ) => { + const addLot = (lotId: number | string, callbackFunction?: (success?: boolean) => void) => { cityssm.postJSON( urlPrefix + "/workOrders/doAddWorkOrderLot", { @@ -280,8 +260,7 @@ declare const bulmaJS: BulmaJS; workOrderLotOccupancies?: recordTypes.LotOccupancy[]; }) => { if (responseJSON.success) { - workOrderLotOccupancies = - responseJSON.workOrderLotOccupancies; + workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; renderRelatedLotsAndOccupancies(); } else { bulmaJS.alert({ @@ -299,8 +278,7 @@ declare const bulmaJS: BulmaJS; }; const addLotFromLotOccupancy = (clickEvent: Event) => { - const lotId = (clickEvent.currentTarget as HTMLElement).dataset - .lotId; + const lotId = (clickEvent.currentTarget as HTMLElement).dataset.lotId; addLot(lotId); }; @@ -309,9 +287,8 @@ declare const bulmaJS: BulmaJS; "#container--lotOccupancies" ) as HTMLElement; - document.querySelector( - ".tabs a[href='#relatedTab--lotOccupancies'] .tag" - ).textContent = workOrderLotOccupancies.length.toString(); + document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent = + workOrderLotOccupancies.length.toString(); if (workOrderLotOccupancies.length === 0) { occupanciesContainerElement.innerHTML = @@ -345,8 +322,7 @@ declare const bulmaJS: BulmaJS; for (const lotOccupancy of workOrderLotOccupancies) { const rowElement = document.createElement("tr"); rowElement.className = "container--lotOccupancy"; - rowElement.dataset.lotOccupancyId = - lotOccupancy.lotOccupancyId.toString(); + rowElement.dataset.lotOccupancyId = lotOccupancy.lotOccupancyId.toString(); const isActive = !( lotOccupancy.occupancyEndDate && @@ -424,19 +400,13 @@ declare const bulmaJS: BulmaJS; ("" + (lotOccupancy.lotOccupancyOccupants.length === 0 ? '(No ' + - cityssm.escapeHTML( - exports.aliases.occupants - ) + + cityssm.escapeHTML(exports.aliases.occupants) + ")" : cityssm.escapeHTML( - lotOccupancy.lotOccupancyOccupants[0] - .occupantName + lotOccupancy.lotOccupancyOccupants[0].occupantName ) + (lotOccupancy.lotOccupancyOccupants.length > 1 - ? " plus " + - (lotOccupancy.lotOccupancyOccupants - .length - - 1) + ? " plus " + (lotOccupancy.lotOccupancyOccupants.length - 1) : "")) + "") + ("" + @@ -456,17 +426,13 @@ declare const bulmaJS: BulmaJS; .querySelector(".button--deleteLotOccupancy") .addEventListener("click", deleteLotOccupancy); - occupanciesContainerElement - .querySelector("tbody") - .append(rowElement); + occupanciesContainerElement.querySelector("tbody").append(rowElement); } }; const deleteLot = (clickEvent: Event) => { const lotId = ( - (clickEvent.currentTarget as HTMLElement).closest( - ".container--lot" - ) as HTMLElement + (clickEvent.currentTarget as HTMLElement).closest(".container--lot") as HTMLElement ).dataset.lotId; const doDelete = () => { @@ -517,13 +483,10 @@ declare const bulmaJS: BulmaJS; }; const renderRelatedLots = () => { - const lotsContainerElement = document.querySelector( - "#container--lots" - ) as HTMLElement; + const lotsContainerElement = document.querySelector("#container--lots") as HTMLElement; - document.querySelector( - ".tabs a[href='#relatedTab--lots'] .tag" - ).textContent = workOrderLots.length.toString(); + document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent = + workOrderLots.length.toString(); if (workOrderLots.length === 0) { lotsContainerElement.innerHTML = @@ -575,9 +538,7 @@ declare const bulmaJS: BulmaJS; "" + ""); - rowElement - .querySelector(".button--deleteLot") - .addEventListener("click", deleteLot); + rowElement.querySelector(".button--deleteLot").addEventListener("click", deleteLot); lotsContainerElement.querySelector("tbody").append(rowElement); } @@ -590,360 +551,570 @@ declare const bulmaJS: BulmaJS; renderRelatedLotsAndOccupancies(); - document - .querySelector("#button--addLotOccupancy") - .addEventListener("click", () => { - let searchFormElement: HTMLFormElement; - let searchResultsContainerElement: HTMLElement; + document.querySelector("#button--addLotOccupancy").addEventListener("click", () => { + let searchFormElement: HTMLFormElement; + let searchResultsContainerElement: HTMLElement; - const doAddLotOccupancy = (clickEvent: Event) => { - const rowElement = ( - clickEvent.currentTarget as HTMLElement - ).closest("tr"); + const doAddLotOccupancy = (clickEvent: Event) => { + const rowElement = (clickEvent.currentTarget as HTMLElement).closest("tr"); - const lotOccupancyId = rowElement.dataset.lotOccupancyId; + const lotOccupancyId = rowElement.dataset.lotOccupancyId; - addLotOccupancy(lotOccupancyId, (success) => { - if (success) { - rowElement.remove(); - } - }); - }; - - const doSearch = (event?: Event) => { - if (event) { - event.preventDefault(); + addLotOccupancy(lotOccupancyId, (success) => { + if (success) { + rowElement.remove(); } + }); + }; - searchResultsContainerElement.innerHTML = - '

' + - '
' + - "Searching..." + - "

"; + const doSearch = (event?: Event) => { + if (event) { + event.preventDefault(); + } - cityssm.postJSON( - urlPrefix + "/lotOccupancies/doSearchLotOccupancies", - searchFormElement, - (responseJSON: { - lotOccupancies: recordTypes.LotOccupancy[]; - }) => { - if (responseJSON.lotOccupancies.length === 0) { - searchResultsContainerElement.innerHTML = - '
' + - '

There are no records that meet the search criteria.

' + - "
"; - - return; - } + searchResultsContainerElement.innerHTML = + '

' + + '
' + + "Searching..." + + "

"; + cityssm.postJSON( + urlPrefix + "/lotOccupancies/doSearchLotOccupancies", + searchFormElement, + (responseJSON: { lotOccupancies: recordTypes.LotOccupancy[] }) => { + if (responseJSON.lotOccupancies.length === 0) { searchResultsContainerElement.innerHTML = - '' + - "" + - "" + - '' + - ("") + - ("") + - "" + - "" + - ("") + - "" + - "" + - "" + - "
" + - exports.aliases.occupancy + - " Type" + exports.aliases.lot + "Start DateEnd Date" + exports.aliases.occupants + "
"; + '
' + + '

There are no records that meet the search criteria.

' + + "
"; - for (const lotOccupancy of responseJSON.lotOccupancies) { - const rowElement = document.createElement("tr"); - rowElement.className = - "container--lotOccupancy"; - rowElement.dataset.lotOccupancyId = - lotOccupancy.lotOccupancyId.toString(); + return; + } - rowElement.innerHTML = - '' + - '" + - "" + - ('' + - cityssm.escapeHTML( - lotOccupancy.occupancyType - ) + - ""); + searchResultsContainerElement.innerHTML = + '' + + "" + + "" + + '' + + ("") + + ("") + + "" + + "" + + ("") + + "" + + "" + + "" + + "
" + exports.aliases.occupancy + " Type" + exports.aliases.lot + "Start DateEnd Date" + exports.aliases.occupants + "
"; - if (lotOccupancy.lotId) { - rowElement.insertAdjacentHTML( - "beforeend", - "" + - cityssm.escapeHTML( - lotOccupancy.lotName - ) + - "" - ); - } else { - rowElement.insertAdjacentHTML( - "beforeend", - "" + - '(No ' + - exports.aliases.lot + - ")" + - "" - ); - } + for (const lotOccupancy of responseJSON.lotOccupancies) { + const rowElement = document.createElement("tr"); + rowElement.className = "container--lotOccupancy"; + rowElement.dataset.lotOccupancyId = + lotOccupancy.lotOccupancyId.toString(); + rowElement.innerHTML = + '' + + '" + + "" + + ('' + + cityssm.escapeHTML(lotOccupancy.occupancyType) + + ""); + + if (lotOccupancy.lotId) { + rowElement.insertAdjacentHTML( + "beforeend", + "" + cityssm.escapeHTML(lotOccupancy.lotName) + "" + ); + } else { rowElement.insertAdjacentHTML( "beforeend", "" + - lotOccupancy.occupancyStartDateString + - "" + - ("" + - (lotOccupancy.occupancyEndDate - ? lotOccupancy.occupancyEndDateString - : '(No End Date)') + - "") + - ("" + - (lotOccupancy.lotOccupancyOccupants - .length === 0 - ? '(No ' + - cityssm.escapeHTML( - exports.aliases.occupants - ) + - ")" - : cityssm.escapeHTML( - lotOccupancy - .lotOccupancyOccupants[0] - .occupantName - ) + - (lotOccupancy - .lotOccupancyOccupants - .length > 1 - ? " plus " + - (lotOccupancy - .lotOccupancyOccupants - .length - - 1) - : "")) + - "") + '(No ' + + exports.aliases.lot + + ")" + + "" ); - - rowElement - .querySelector(".button--addLotOccupancy") - .addEventListener( - "click", - doAddLotOccupancy - ); - - searchResultsContainerElement - .querySelector("tbody") - .append(rowElement); } - } - ); - }; - cityssm.openHtmlModal("workOrder-addLotOccupancy", { - onshow: (modalElement) => { - los.populateAliases(modalElement); - - searchFormElement = modalElement.querySelector("form"); - searchResultsContainerElement = - modalElement.querySelector( - "#resultsContainer--lotOccupancyAdd" + rowElement.insertAdjacentHTML( + "beforeend", + "" + + lotOccupancy.occupancyStartDateString + + "" + + ("" + + (lotOccupancy.occupancyEndDate + ? lotOccupancy.occupancyEndDateString + : '(No End Date)') + + "") + + ("" + + (lotOccupancy.lotOccupancyOccupants.length === 0 + ? '(No ' + + cityssm.escapeHTML(exports.aliases.occupants) + + ")" + : cityssm.escapeHTML( + lotOccupancy.lotOccupancyOccupants[0].occupantName + ) + + (lotOccupancy.lotOccupancyOccupants.length > 1 + ? " plus " + + (lotOccupancy.lotOccupancyOccupants.length - 1) + : "")) + + "") ); - ( - modalElement.querySelector( - "#lotOccupancySearch--notWorkOrderId" - ) as HTMLInputElement - ).value = workOrderId; + rowElement + .querySelector(".button--addLotOccupancy") + .addEventListener("click", doAddLotOccupancy); - ( - modalElement.querySelector( - "#lotOccupancySearch--occupancyEffectiveDateString" - ) as HTMLInputElement - ).value = ( - document.querySelector( - "#workOrderEdit--workOrderOpenDateString" - ) as HTMLInputElement - ).value; + searchResultsContainerElement.querySelector("tbody").append(rowElement); + } + } + ); + }; - doSearch(); - }, - onshown: (modalElement) => { - bulmaJS.toggleHtmlClipped(); + cityssm.openHtmlModal("workOrder-addLotOccupancy", { + onshow: (modalElement) => { + los.populateAliases(modalElement); - modalElement - .querySelector("#lotOccupancySearch--occupantName") - .addEventListener("change", doSearch); - modalElement - .querySelector("#lotOccupancySearch--lotName") - .addEventListener("change", doSearch); + searchFormElement = modalElement.querySelector("form"); + searchResultsContainerElement = modalElement.querySelector( + "#resultsContainer--lotOccupancyAdd" + ); - searchFormElement.addEventListener("submit", doSearch); - }, - onremoved: () => { - bulmaJS.toggleHtmlClipped(); + ( + modalElement.querySelector( + "#lotOccupancySearch--notWorkOrderId" + ) as HTMLInputElement + ).value = workOrderId; + + ( + modalElement.querySelector( + "#lotOccupancySearch--occupancyEffectiveDateString" + ) as HTMLInputElement + ).value = ( + document.querySelector( + "#workOrderEdit--workOrderOpenDateString" + ) as HTMLInputElement + ).value; + + doSearch(); + }, + onshown: (modalElement) => { + bulmaJS.toggleHtmlClipped(); + + modalElement + .querySelector("#lotOccupancySearch--occupantName") + .addEventListener("change", doSearch); + modalElement + .querySelector("#lotOccupancySearch--lotName") + .addEventListener("change", doSearch); + + searchFormElement.addEventListener("submit", doSearch); + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + } + }); + }); + + document.querySelector("#button--addLot").addEventListener("click", () => { + let searchFormElement: HTMLFormElement; + let searchResultsContainerElement: HTMLElement; + + const doAddLot = (clickEvent: Event) => { + const rowElement = (clickEvent.currentTarget as HTMLElement).closest("tr"); + + const lotId = rowElement.dataset.lotId; + + addLot(lotId, (success) => { + if (success) { + rowElement.remove(); } }); - }); + }; - document - .querySelector("#button--addLot") - .addEventListener("click", () => { - let searchFormElement: HTMLFormElement; - let searchResultsContainerElement: HTMLElement; + const doSearch = (event?: Event) => { + if (event) { + event.preventDefault(); + } - const doAddLot = (clickEvent: Event) => { - const rowElement = ( - clickEvent.currentTarget as HTMLElement - ).closest("tr"); - - const lotId = rowElement.dataset.lotId; - - addLot(lotId, (success) => { - if (success) { - rowElement.remove(); - } - }); - }; - - const doSearch = (event?: Event) => { - if (event) { - event.preventDefault(); - } - - searchResultsContainerElement.innerHTML = - '

' + - '
' + - "Searching..." + - "

"; - - cityssm.postJSON( - urlPrefix + "/lots/doSearchLots", - searchFormElement, - (responseJSON: { lots: recordTypes.Lot[] }) => { - if (responseJSON.lots.length === 0) { - searchResultsContainerElement.innerHTML = - '
' + - '

There are no records that meet the search criteria.

' + - "
"; - - return; - } + searchResultsContainerElement.innerHTML = + '

' + + '
' + + "Searching..." + + "

"; + cityssm.postJSON( + urlPrefix + "/lots/doSearchLots", + searchFormElement, + (responseJSON: { lots: recordTypes.Lot[] }) => { + if (responseJSON.lots.length === 0) { searchResultsContainerElement.innerHTML = - '' + - "" + - "" + - '' + - ("") + - ("") + - ("") + - "" + - "" + - "" + - "" + - "
" + exports.aliases.lot + "" + exports.aliases.map + "" + exports.aliases.lot + " TypeStatus
"; + '
' + + '

There are no records that meet the search criteria.

' + + "
"; - for (const lot of responseJSON.lots) { - const rowElement = document.createElement("tr"); - rowElement.className = "container--lot"; - rowElement.dataset.lotId = lot.lotId.toString(); - - rowElement.innerHTML = - '' + - '" + - "" + - ('' + - cityssm.escapeHTML(lot.lotName) + - "") + - "" + - cityssm.escapeHTML(lot.mapName) + - "" + - ("" + - cityssm.escapeHTML(lot.lotType) + - "") + - ("" + - cityssm.escapeHTML(lot.lotStatus) + - ""); - - rowElement - .querySelector(".button--addLot") - .addEventListener("click", doAddLot); - - searchResultsContainerElement - .querySelector("tbody") - .append(rowElement); - } - } - ); - }; - - cityssm.openHtmlModal("workOrder-addLot", { - onshow: (modalElement) => { - los.populateAliases(modalElement); - - searchFormElement = modalElement.querySelector("form"); - searchResultsContainerElement = - modalElement.querySelector( - "#resultsContainer--lotAdd" - ); - - ( - modalElement.querySelector( - "#lotSearch--notWorkOrderId" - ) as HTMLInputElement - ).value = workOrderId; - - const lotStatusElement = modalElement.querySelector( - "#lotSearch--lotStatusId" - ) as HTMLSelectElement; - - for (const lotStatus of exports.lotStatuses as recordTypes.LotStatus[]) { - const optionElement = - document.createElement("option"); - optionElement.value = - lotStatus.lotStatusId.toString(); - optionElement.textContent = lotStatus.lotStatus; - lotStatusElement.append(optionElement); + return; } - doSearch(); - }, - onshown: (modalElement) => { - bulmaJS.toggleHtmlClipped(); + searchResultsContainerElement.innerHTML = + '' + + "" + + "" + + '' + + ("") + + ("") + + ("") + + "" + + "" + + "" + + "" + + "
" + exports.aliases.lot + "" + exports.aliases.map + "" + exports.aliases.lot + " TypeStatus
"; - modalElement - .querySelector("#lotSearch--lotName") - .addEventListener("change", doSearch); + for (const lot of responseJSON.lots) { + const rowElement = document.createElement("tr"); + rowElement.className = "container--lot"; + rowElement.dataset.lotId = lot.lotId.toString(); - modalElement - .querySelector("#lotSearch--lotStatusId") - .addEventListener("change", doSearch); + rowElement.innerHTML = + '' + + '" + + "" + + ('' + + cityssm.escapeHTML(lot.lotName) + + "") + + "" + + cityssm.escapeHTML(lot.mapName) + + "" + + ("" + cityssm.escapeHTML(lot.lotType) + "") + + ("" + cityssm.escapeHTML(lot.lotStatus) + ""); - searchFormElement.addEventListener("submit", doSearch); - }, - onremoved: () => { - bulmaJS.toggleHtmlClipped(); + rowElement + .querySelector(".button--addLot") + .addEventListener("click", doAddLot); + + searchResultsContainerElement.querySelector("tbody").append(rowElement); + } } - }); + ); + }; + + cityssm.openHtmlModal("workOrder-addLot", { + onshow: (modalElement) => { + los.populateAliases(modalElement); + + searchFormElement = modalElement.querySelector("form"); + searchResultsContainerElement = modalElement.querySelector( + "#resultsContainer--lotAdd" + ); + + ( + modalElement.querySelector("#lotSearch--notWorkOrderId") as HTMLInputElement + ).value = workOrderId; + + const lotStatusElement = modalElement.querySelector( + "#lotSearch--lotStatusId" + ) as HTMLSelectElement; + + for (const lotStatus of exports.lotStatuses as recordTypes.LotStatus[]) { + const optionElement = document.createElement("option"); + optionElement.value = lotStatus.lotStatusId.toString(); + optionElement.textContent = lotStatus.lotStatus; + lotStatusElement.append(optionElement); + } + + doSearch(); + }, + onshown: (modalElement) => { + bulmaJS.toggleHtmlClipped(); + + modalElement + .querySelector("#lotSearch--lotName") + .addEventListener("change", doSearch); + + modalElement + .querySelector("#lotSearch--lotStatusId") + .addEventListener("change", doSearch); + + searchFormElement.addEventListener("submit", doSearch); + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + } }); + }); } /* * Comments */ + let workOrderComments: recordTypes.WorkOrderComment[] = exports.workOrderComments; + delete exports.workOrderComments; + + const openEditWorkOrderComment = (clickEvent: Event) => { + const workOrderCommentId = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).closest("tr").dataset.workOrderCommentId, + 10 + ); + + const workOrderComment = workOrderComments.find((currentComment) => { + return currentComment.workOrderCommentId === workOrderCommentId; + }); + + console.log(workOrderComments) + + let editFormElement: HTMLFormElement; + let editCloseModalFunction: () => void; + + const editComment = (submitEvent: SubmitEvent) => { + submitEvent.preventDefault(); + + cityssm.postJSON( + urlPrefix + "/workOrders/doUpdateWorkOrderComment", + editFormElement, + (responseJSON: { + success: boolean; + errorMessage?: string; + workOrderComments?: recordTypes.WorkOrderComment[]; + }) => { + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments; + editCloseModalFunction(); + renderWorkOrderComments(); + } else { + bulmaJS.alert({ + title: "Error Updating Comment", + message: responseJSON.errorMessage, + contextualColorName: "danger" + }); + } + } + ); + }; + + cityssm.openHtmlModal("workOrder-editComment", { + onshow: (modalElement) => { + ( + modalElement.querySelector( + "#workOrderCommentEdit--workOrderId" + ) as HTMLInputElement + ).value = workOrderId; + ( + modalElement.querySelector( + "#workOrderCommentEdit--workOrderCommentId" + ) as HTMLInputElement + ).value = workOrderCommentId.toString(); + + ( + modalElement.querySelector( + "#workOrderCommentEdit--workOrderComment" + ) as HTMLInputElement + ).value = workOrderComment.workOrderComment; + ( + modalElement.querySelector( + "#workOrderCommentEdit--workOrderCommentDateString" + ) as HTMLInputElement + ).value = workOrderComment.workOrderCommentDateString; + ( + modalElement.querySelector( + "#workOrderCommentEdit--workOrderCommentTimeString" + ) as HTMLInputElement + ).value = workOrderComment.workOrderCommentTimeString; + }, + onshown: (modalElement, closeModalFunction) => { + bulmaJS.toggleHtmlClipped(); + + los.initializeDatePickers(modalElement); + los.initializeTimePickers(modalElement); + + ( + modalElement.querySelector( + "#workOrderCommentEdit--workOrderComment" + ) as HTMLTextAreaElement + ).focus(); + + editFormElement = modalElement.querySelector("form"); + editFormElement.addEventListener("submit", editComment); + + editCloseModalFunction = closeModalFunction; + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + } + }); + }; + + const deleteWorkOrderComment = (clickEvent: Event) => { + const workOrderCommentId = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).closest("tr").dataset.workOrderCommentId, + 10 + ); + + const doDelete = () => { + cityssm.postJSON( + urlPrefix + "/workOrders/doDeleteWorkOrderComment", + { + workOrderId, + workOrderCommentId + }, + (responseJSON: { + success: boolean; + errorMessage?: string; + workOrderComments: recordTypes.WorkOrderComment[]; + }) => { + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments; + renderWorkOrderComments(); + } 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 renderWorkOrderComments = () => { + const containerElement = document.querySelector( + "#container--workOrderComments" + ) as HTMLElement; + + if (workOrderComments.length === 0) { + containerElement.innerHTML = + '
' + + '

There are no comments to display.

' + + "
"; + return; + } + + const tableElement = document.createElement("table"); + tableElement.className = "table is-fullwidth is-striped is-hoverable"; + tableElement.innerHTML = + "" + + "Commentor" + + "Comment Date" + + "Comment" + + 'Options' + + "" + + ""; + + for (const workOrderComment of workOrderComments) { + const tableRowElement = document.createElement("tr"); + tableRowElement.dataset.workOrderCommentId = workOrderComment.workOrderCommentId.toString(); + + tableRowElement.innerHTML = + "" + + cityssm.escapeHTML(workOrderComment.recordCreate_userName) + + "" + + "" + + workOrderComment.workOrderCommentDateString + + (workOrderComment.workOrderCommentTime === 0 + ? "" + : " " + workOrderComment.workOrderCommentTimeString) + + "" + + "" + + cityssm.escapeHTML(workOrderComment.workOrderComment) + + "" + + ('' + + '
' + + ('") + + ('") + + "
" + + ""); + + tableRowElement + .querySelector(".button--edit") + .addEventListener("click", openEditWorkOrderComment); + tableRowElement + .querySelector(".button--delete") + .addEventListener("click", deleteWorkOrderComment); + + tableElement.querySelector("tbody").append(tableRowElement); + } + + containerElement.innerHTML = ""; + containerElement.append(tableElement); + }; + + const openAddCommentModal = () => { + let addCommentCloseModalFunction: () => void; + + const doAddComment = (formEvent: SubmitEvent) => { + formEvent.preventDefault(); + + cityssm.postJSON( + urlPrefix + "/workOrders/doAddWorkOrderComment", + formEvent.currentTarget, + (responseJSON: { + success: boolean; + workOrderComments?: recordTypes.WorkOrderComment[]; + }) => { + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments; + renderWorkOrderComments(); + addCommentCloseModalFunction(); + } + } + ); + }; + + cityssm.openHtmlModal("workOrder-addComment", { + onshow(modalElement) { + los.populateAliases(modalElement); + ( + modalElement.querySelector( + "#workOrderCommentAdd--workOrderId" + ) as HTMLInputElement + ).value = workOrderId; + modalElement.querySelector("form").addEventListener("submit", doAddComment); + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + addCommentCloseModalFunction = closeModalFunction; + ( + modalElement.querySelector("#workOrderCommentAdd--workOrderComment") as HTMLTextAreaElement + ).focus(); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + (document.querySelector("#workOrderComments--add") as HTMLButtonElement).focus(); + } + }); + }; + + if (!isCreate) { + document.querySelector("#workOrderComments--add").addEventListener("click", openAddCommentModal); + renderWorkOrderComments(); + } + /* * Milestones */ if (!isCreate) { - workOrderMilestones = - exports.workOrderMilestones as recordTypes.WorkOrderMilestone[]; + workOrderMilestones = exports.workOrderMilestones as recordTypes.WorkOrderMilestone[]; delete exports.workOrderMilestones; const processMilestoneResponse = (responseJSON: { @@ -977,14 +1148,9 @@ declare const bulmaJS: BulmaJS; 10 ); - const workOrderMilestone = workOrderMilestones.find( - (currentMilestone) => { - return ( - currentMilestone.workOrderMilestoneId === - workOrderMilestoneId - ); - } - ); + const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { + return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; + }); const doComplete = () => { cityssm.postJSON( @@ -1001,8 +1167,7 @@ declare const bulmaJS: BulmaJS; title: "Complete Milestone", message: "Are you sure you want to complete this milestone?" + - (workOrderMilestone.workOrderMilestoneDateString > - currentDateString + (workOrderMilestone.workOrderMilestoneDateString > currentDateString ? "
Note that this milestone is expected to be completed in the future." : ""), messageIsHtml: true, @@ -1089,14 +1254,9 @@ declare const bulmaJS: BulmaJS; 10 ); - const workOrderMilestone = workOrderMilestones.find( - (currentMilestone) => { - return ( - currentMilestone.workOrderMilestoneId === - workOrderMilestoneId - ); - } - ); + const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { + return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; + }); let editCloseModalFunction: () => void; @@ -1131,8 +1291,7 @@ declare const bulmaJS: BulmaJS; modalElement.querySelector( "#milestoneEdit--workOrderMilestoneId" ) as HTMLInputElement - ).value = - workOrderMilestone.workOrderMilestoneId.toString(); + ).value = workOrderMilestone.workOrderMilestoneId.toString(); const milestoneTypeElement = modalElement.querySelector( "#milestoneEdit--workOrderMilestoneTypeId" @@ -1143,10 +1302,8 @@ declare const bulmaJS: BulmaJS; for (const milestoneType of exports.workOrderMilestoneTypes as recordTypes.WorkOrderMilestoneType[]) { const optionElement = document.createElement("option"); - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString(); - optionElement.textContent = - milestoneType.workOrderMilestoneType; + optionElement.value = milestoneType.workOrderMilestoneTypeId.toString(); + optionElement.textContent = milestoneType.workOrderMilestoneType; if ( milestoneType.workOrderMilestoneTypeId === @@ -1159,15 +1316,11 @@ declare const bulmaJS: BulmaJS; milestoneTypeElement.append(optionElement); } - if ( - !milestoneTypeFound && - workOrderMilestone.workOrderMilestoneTypeId - ) { + if (!milestoneTypeFound && workOrderMilestone.workOrderMilestoneTypeId) { const optionElement = document.createElement("option"); optionElement.value = workOrderMilestone.workOrderMilestoneTypeId.toString(); - optionElement.textContent = - workOrderMilestone.workOrderMilestoneType; + optionElement.textContent = workOrderMilestone.workOrderMilestoneType; optionElement.selected = true; milestoneTypeElement.append(optionElement); } @@ -1183,8 +1336,7 @@ declare const bulmaJS: BulmaJS; modalElement.querySelector( "#milestoneEdit--workOrderMilestoneTimeString" ) as HTMLInputElement - ).value = - workOrderMilestone.workOrderMilestoneTimeString; + ).value = workOrderMilestone.workOrderMilestoneTimeString; } ( @@ -1197,13 +1349,11 @@ declare const bulmaJS: BulmaJS; editCloseModalFunction = closeModalFunction; bulmaJS.toggleHtmlClipped(); - + los.initializeDatePickers(modalElement); los.initializeTimePickers(modalElement); - modalElement - .querySelector("form") - .addEventListener("submit", doEdit); + modalElement.querySelector("form").addEventListener("submit", doEdit); }, onremoved: () => { bulmaJS.toggleHtmlClipped(); @@ -1227,8 +1377,7 @@ declare const bulmaJS: BulmaJS; for (const milestone of workOrderMilestones) { const panelBlockElement = document.createElement("div"); - panelBlockElement.className = - "panel-block is-block container--milestone"; + panelBlockElement.className = "panel-block is-block container--milestone"; panelBlockElement.dataset.workOrderMilestoneId = milestone.workOrderMilestoneId.toString(); @@ -1251,9 +1400,7 @@ declare const bulmaJS: BulmaJS; ('
' + (milestone.workOrderMilestoneTypeId ? "" + - cityssm.escapeHTML( - milestone.workOrderMilestoneType - ) + + cityssm.escapeHTML(milestone.workOrderMilestoneType) + "
" : "") + milestone.workOrderMilestoneDateString + @@ -1262,9 +1409,7 @@ declare const bulmaJS: BulmaJS; : "") + "
" + '' + - cityssm.escapeHTML( - milestone.workOrderMilestoneDescription - ) + + cityssm.escapeHTML(milestone.workOrderMilestoneDescription) + "" + "
") + ('
' + @@ -1322,105 +1467,95 @@ declare const bulmaJS: BulmaJS; renderMilestones(); - document - .querySelector("#button--addMilestone") - .addEventListener("click", () => { - let addModalElement: HTMLElement; - let addCloseModalFunction: () => void; + document.querySelector("#button--addMilestone").addEventListener("click", () => { + let addModalElement: HTMLElement; + let addCloseModalFunction: () => void; - const doAdd = (submitEvent: SubmitEvent) => { - submitEvent.preventDefault(); + const doAdd = (submitEvent: SubmitEvent) => { + submitEvent.preventDefault(); - const currentDateString = cityssm.dateToString(new Date()); + const currentDateString = cityssm.dateToString(new Date()); - const _doAdd = () => { - cityssm.postJSON( - urlPrefix + "/workOrders/doAddWorkOrderMilestone", - submitEvent.currentTarget, - (responseJSON: { - success: boolean; - errorMessage?: string; - workOrderMilestones?: recordTypes.WorkOrderMilestone[]; - }) => { - processMilestoneResponse(responseJSON); + const _doAdd = () => { + cityssm.postJSON( + urlPrefix + "/workOrders/doAddWorkOrderMilestone", + submitEvent.currentTarget, + (responseJSON: { + success: boolean; + errorMessage?: string; + workOrderMilestones?: recordTypes.WorkOrderMilestone[]; + }) => { + processMilestoneResponse(responseJSON); - if (responseJSON.success) { - addCloseModalFunction(); - } + if (responseJSON.success) { + addCloseModalFunction(); } - ); - }; - - if ( - ( - addModalElement.querySelector( - "#milestoneAdd--workOrderMilestoneDateString" - ) as HTMLInputElement - ).value < currentDateString - ) { - bulmaJS.confirm({ - title: "Milestone Date in the Past", - message: - "Are you sure you want to create a milestone with a date in the past?", - contextualColorName: "warning", - okButton: { - text: "Yes, Create a Past Milestone", - callbackFunction: _doAdd - } - }); - } else { - _doAdd(); - } + } + ); }; - cityssm.openHtmlModal("workOrder-addMilestone", { - onshow: (modalElement) => { - ( - modalElement.querySelector( - "#milestoneAdd--workOrderId" - ) as HTMLInputElement - ).value = workOrderId; - - const milestoneTypeElement = modalElement.querySelector( - "#milestoneAdd--workOrderMilestoneTypeId" - ) as HTMLSelectElement; - - for (const milestoneType of exports.workOrderMilestoneTypes as recordTypes.WorkOrderMilestoneType[]) { - const optionElement = - document.createElement("option"); - - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString(); - optionElement.textContent = - milestoneType.workOrderMilestoneType; - - milestoneTypeElement.append(optionElement); + if ( + ( + addModalElement.querySelector( + "#milestoneAdd--workOrderMilestoneDateString" + ) as HTMLInputElement + ).value < currentDateString + ) { + bulmaJS.confirm({ + title: "Milestone Date in the Past", + message: + "Are you sure you want to create a milestone with a date in the past?", + contextualColorName: "warning", + okButton: { + text: "Yes, Create a Past Milestone", + callbackFunction: _doAdd } + }); + } else { + _doAdd(); + } + }; - ( - modalElement.querySelector( - "#milestoneAdd--workOrderMilestoneDateString" - ) as HTMLInputElement - ).valueAsDate = new Date(); + cityssm.openHtmlModal("workOrder-addMilestone", { + onshow: (modalElement) => { + ( + modalElement.querySelector("#milestoneAdd--workOrderId") as HTMLInputElement + ).value = workOrderId; - }, - onshown: (modalElement, closeModalFunction) => { - addModalElement = modalElement; - addCloseModalFunction = closeModalFunction; + const milestoneTypeElement = modalElement.querySelector( + "#milestoneAdd--workOrderMilestoneTypeId" + ) as HTMLSelectElement; - los.initializeDatePickers(modalElement); - los.initializeTimePickers(modalElement); + for (const milestoneType of exports.workOrderMilestoneTypes as recordTypes.WorkOrderMilestoneType[]) { + const optionElement = document.createElement("option"); - bulmaJS.toggleHtmlClipped(); + optionElement.value = milestoneType.workOrderMilestoneTypeId.toString(); + optionElement.textContent = milestoneType.workOrderMilestoneType; - modalElement - .querySelector("form") - .addEventListener("submit", doAdd); - }, - onremoved: () => { - bulmaJS.toggleHtmlClipped(); + milestoneTypeElement.append(optionElement); } - }); + + ( + modalElement.querySelector( + "#milestoneAdd--workOrderMilestoneDateString" + ) as HTMLInputElement + ).valueAsDate = new Date(); + }, + onshown: (modalElement, closeModalFunction) => { + addModalElement = modalElement; + addCloseModalFunction = closeModalFunction; + + los.initializeDatePickers(modalElement); + los.initializeTimePickers(modalElement); + + bulmaJS.toggleHtmlClipped(); + + modalElement.querySelector("form").addEventListener("submit", doAdd); + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + } }); + }); } })(); diff --git a/public/html/workOrder-addComment.html b/public/html/workOrder-addComment.html new file mode 100644 index 00000000..d4981ef0 --- /dev/null +++ b/public/html/workOrder-addComment.html @@ -0,0 +1,29 @@ + \ No newline at end of file diff --git a/public/html/workOrder-editComment.html b/public/html/workOrder-editComment.html new file mode 100644 index 00000000..18f8f83b --- /dev/null +++ b/public/html/workOrder-editComment.html @@ -0,0 +1,54 @@ + \ No newline at end of file diff --git a/public/javascripts/workOrderEdit.min.js b/public/javascripts/workOrderEdit.min.js index eb40a7dc..4ab11678 100644 --- a/public/javascripts/workOrderEdit.min.js +++ b/public/javascripts/workOrderEdit.min.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,o=document.querySelector("#workOrderEdit--workOrderId").value,s=""===o,r=document.querySelector("#form--workOrderEdit");let a;if(e.initializeDatePickers(r.querySelector("#workOrderEdit--workOrderOpenDateString").closest(".field")),e.initializeUnlockFieldButtons(r),r.addEventListener("submit",e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/"+(s?"doCreateWorkOrder":"doUpdateWorkOrder"),e.currentTarget,e=>{e.success?s?window.location.href=t+"/workOrders/"+e.workOrderId+"/edit":bulmaJS.alert({message:"Work Order Updated Successfully",contextualColorName:"success"}):bulmaJS.alert({title:"Error Updating Work Order",message:e.errorMessage,contextualColorName:"danger"})})}),!s){const e=()=>{cityssm.postJSON(t+"/workOrders/doCloseWorkOrder",{workOrderId:o},e=>{e.success?window.location.href=t+"/workOrders/"+o:bulmaJS.alert({title:"Error Closing Work Order",message:e.errorMessage,contextualColorName:"danger"})})};document.querySelector("#button--closeWorkOrder").addEventListener("click",()=>{a.some(e=>!e.workOrderMilestoneCompletionDate)?bulmaJS.confirm({title:"Close Work Order with Outstanding Milestones",message:"Are you sure you want to close this work order with outstanding milestones?",contextualColorName:"danger",okButton:{text:"Yes, Close Work Order",callbackFunction:e}}):bulmaJS.confirm({title:"Close Work Order",message:"Are you sure you want to close this work order?",contextualColorName:"info",okButton:{text:"Yes, Close Work Order",callbackFunction:e}})});const s=()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrder",{workOrderId:o},e=>{e.success?window.location.href=t+"/workOrders":bulmaJS.alert({title:"Error Deleting Work Order",message:e.errorMessage,contextualColorName:"danger"})})};document.querySelector("#button--deleteWorkOrder").addEventListener("click",e=>{e.preventDefault(),bulmaJS.confirm({title:"Delete Work Order",message:"Are you sure you want to delete this work order?",contextualColorName:"warning",okButton:{text:"Yes, Delete Work Order",callbackFunction:s}})})}if(!s){let s=exports.workOrderLots;delete exports.workOrderLots;let r=exports.workOrderLotOccupancies;delete exports.workOrderLotOccupancies;const a=e=>{const s=e.currentTarget.closest(".container--lotOccupancy").dataset.lotOccupancyId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" "+exports.aliases.occupancy+" Relationship",message:"Are you sure you want to remove the relationship to this "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupancy.toLowerCase()+" record from this work order? Note that the record will remain.",contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderLotOccupancy",{workOrderId:o,lotOccupancyId:s},e=>{e.success?(r=e.workOrderLotOccupancies,p()):bulmaJS.alert({title:"Error Deleting Relationship",message:e.errorMessage,contextualColorName:"danger"})})}}})},n=(e,r)=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderLot",{workOrderId:o,lotId:e},e=>{e.success?(s=e.workOrderLots,p()):bulmaJS.alert({title:"Error Adding "+exports.aliases.lot,message:e.errorMessage,contextualColorName:"danger"}),r&&r(e.success)})},l=(e,s)=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderLotOccupancy",{workOrderId:o,lotOccupancyId:e},e=>{e.success?(r=e.workOrderLotOccupancies,p()):bulmaJS.alert({title:"Error Adding "+exports.aliases.occupancy,message:e.errorMessage,contextualColorName:"danger"}),s&&s(e.success)})},c=e=>{const t=e.currentTarget.dataset.lotId;n(t)},i=()=>{const e=document.querySelector("#container--lotOccupancies");if(document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent=r.length.toString(),0===r.length)return void(e.innerHTML='

There are no '+exports.aliases.occupancies.toLowerCase()+" associated with this work order.

");e.innerHTML='
'+exports.aliases.occupancy+" Type"+exports.aliases.lot+"Start DateEnd Date"+exports.aliases.occupants+'
';const o=cityssm.dateToString(new Date);for(const n of r){const r=document.createElement("tr");r.className="container--lotOccupancy",r.dataset.lotOccupancyId=n.lotOccupancyId.toString();const l=!(n.occupancyEndDate&&n.occupancyEndDateStringn.lotId===e.lotId);r.innerHTML=''+(l?'':'')+''+cityssm.escapeHTML(n.occupancyType)+"",n.lotId?r.insertAdjacentHTML("beforeend",""+cityssm.escapeHTML(n.lotName)+(i?"":' ')+""):r.insertAdjacentHTML("beforeend",'(No '+exports.aliases.lot+")"),r.insertAdjacentHTML("beforeend",""+n.occupancyStartDateString+""+(n.occupancyEndDate?n.occupancyEndDateString:'(No End Date)')+""+(0===n.lotOccupancyOccupants.length?'(No '+cityssm.escapeHTML(exports.aliases.occupants)+")":cityssm.escapeHTML(n.lotOccupancyOccupants[0].occupantName)+(n.lotOccupancyOccupants.length>1?" plus "+(n.lotOccupancyOccupants.length-1):""))+''),n.lotId&&!i&&r.querySelector(".button--addLot").addEventListener("click",c),r.querySelector(".button--deleteLotOccupancy").addEventListener("click",a),e.querySelector("tbody").append(r)}},d=e=>{const r=e.currentTarget.closest(".container--lot").dataset.lotId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" "+exports.aliases.occupancy+" Relationship",message:"Are you sure you want to remove the relationship to this "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupancy.toLowerCase()+" record from this work order? Note that the record will remain.",contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderLot",{workOrderId:o,lotId:r},e=>{e.success?(s=e.workOrderLots,p()):bulmaJS.alert({title:"Error Deleting Relationship",message:e.errorMessage,contextualColorName:"danger"})})}}})},u=()=>{const e=document.querySelector("#container--lots");if(document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent=s.length.toString(),0!==s.length){e.innerHTML='
'+exports.aliases.lot+""+exports.aliases.map+""+exports.aliases.lot+' TypeStatus
';for(const o of s){const s=document.createElement("tr");s.className="container--lot",s.dataset.lotId=o.lotId.toString(),s.innerHTML=''+cityssm.escapeHTML(o.lotName)+""+cityssm.escapeHTML(o.mapName)+""+cityssm.escapeHTML(o.lotType)+""+cityssm.escapeHTML(o.lotStatus)+'',s.querySelector(".button--deleteLot").addEventListener("click",d),e.querySelector("tbody").append(s)}}else e.innerHTML='

There are no '+exports.aliases.lots.toLowerCase()+" associated with this work order.

"},p=()=>{i(),u()};p(),document.querySelector("#button--addLotOccupancy").addEventListener("click",()=>{let s,r;const a=e=>{const t=e.currentTarget.closest("tr"),o=t.dataset.lotOccupancyId;l(o,e=>{e&&t.remove()})},n=e=>{e&&e.preventDefault(),r.innerHTML='


Searching...

',cityssm.postJSON(t+"/lotOccupancies/doSearchLotOccupancies",s,e=>{if(0!==e.lotOccupancies.length){r.innerHTML='
'+exports.aliases.occupancy+" Type"+exports.aliases.lot+"Start DateEnd Date"+exports.aliases.occupants+"
";for(const t of e.lotOccupancies){const e=document.createElement("tr");e.className="container--lotOccupancy",e.dataset.lotOccupancyId=t.lotOccupancyId.toString(),e.innerHTML=''+cityssm.escapeHTML(t.occupancyType)+"",t.lotId?e.insertAdjacentHTML("beforeend",""+cityssm.escapeHTML(t.lotName)+""):e.insertAdjacentHTML("beforeend",'(No '+exports.aliases.lot+")"),e.insertAdjacentHTML("beforeend",""+t.occupancyStartDateString+""+(t.occupancyEndDate?t.occupancyEndDateString:'(No End Date)')+""+(0===t.lotOccupancyOccupants.length?'(No '+cityssm.escapeHTML(exports.aliases.occupants)+")":cityssm.escapeHTML(t.lotOccupancyOccupants[0].occupantName)+(t.lotOccupancyOccupants.length>1?" plus "+(t.lotOccupancyOccupants.length-1):""))+""),e.querySelector(".button--addLotOccupancy").addEventListener("click",a),r.querySelector("tbody").append(e)}}else r.innerHTML='

There are no records that meet the search criteria.

'})};cityssm.openHtmlModal("workOrder-addLotOccupancy",{onshow:t=>{e.populateAliases(t),s=t.querySelector("form"),r=t.querySelector("#resultsContainer--lotOccupancyAdd"),t.querySelector("#lotOccupancySearch--notWorkOrderId").value=o,t.querySelector("#lotOccupancySearch--occupancyEffectiveDateString").value=document.querySelector("#workOrderEdit--workOrderOpenDateString").value,n()},onshown:e=>{bulmaJS.toggleHtmlClipped(),e.querySelector("#lotOccupancySearch--occupantName").addEventListener("change",n),e.querySelector("#lotOccupancySearch--lotName").addEventListener("change",n),s.addEventListener("submit",n)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),document.querySelector("#button--addLot").addEventListener("click",()=>{let s,r;const a=e=>{const t=e.currentTarget.closest("tr"),o=t.dataset.lotId;n(o,e=>{e&&t.remove()})},l=e=>{e&&e.preventDefault(),r.innerHTML='


Searching...

',cityssm.postJSON(t+"/lots/doSearchLots",s,e=>{if(0!==e.lots.length){r.innerHTML='
'+exports.aliases.lot+""+exports.aliases.map+""+exports.aliases.lot+" TypeStatus
";for(const t of e.lots){const e=document.createElement("tr");e.className="container--lot",e.dataset.lotId=t.lotId.toString(),e.innerHTML=''+cityssm.escapeHTML(t.lotName)+""+cityssm.escapeHTML(t.mapName)+""+cityssm.escapeHTML(t.lotType)+""+cityssm.escapeHTML(t.lotStatus)+"",e.querySelector(".button--addLot").addEventListener("click",a),r.querySelector("tbody").append(e)}}else r.innerHTML='

There are no records that meet the search criteria.

'})};cityssm.openHtmlModal("workOrder-addLot",{onshow:t=>{e.populateAliases(t),s=t.querySelector("form"),r=t.querySelector("#resultsContainer--lotAdd"),t.querySelector("#lotSearch--notWorkOrderId").value=o;const a=t.querySelector("#lotSearch--lotStatusId");for(const e of exports.lotStatuses){const t=document.createElement("option");t.value=e.lotStatusId.toString(),t.textContent=e.lotStatus,a.append(t)}l()},onshown:e=>{bulmaJS.toggleHtmlClipped(),e.querySelector("#lotSearch--lotName").addEventListener("change",l),e.querySelector("#lotSearch--lotStatusId").addEventListener("change",l),s.addEventListener("submit",l)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})})}if(!s){a=exports.workOrderMilestones,delete exports.workOrderMilestones;const s=e=>{e.success?(a=e.workOrderMilestones,i()):bulmaJS.alert({title:"Error Reopening Milestone",message:e.errorMessage,contextualColorName:"danger"})},r=e=>{e.preventDefault();const r=cityssm.dateToString(new Date),n=Number.parseInt(e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId,10),l=a.find(e=>e.workOrderMilestoneId===n);bulmaJS.confirm({title:"Complete Milestone",message:"Are you sure you want to complete this milestone?"+(l.workOrderMilestoneDateString>r?"
Note that this milestone is expected to be completed in the future.":""),messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Complete Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doCompleteWorkOrderMilestone",{workOrderId:o,workOrderMilestoneId:n},s)}}})},n=e=>{e.preventDefault();const r=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Reopen Milestone",message:"Are you sure you want to remove the completion status from this milestone, and reopen it?",contextualColorName:"warning",okButton:{text:"Yes, Reopen Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doReopenWorkOrderMilestone",{workOrderId:o,workOrderMilestoneId:r},s)}}})},l=e=>{e.preventDefault();const r=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Delete Milestone",message:"Are you sure you want to delete this milestone?",contextualColorName:"warning",okButton:{text:"Yes, Delete Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderMilestone",{workOrderMilestoneId:r,workOrderId:o},s)}}})},c=r=>{r.preventDefault();const n=Number.parseInt(r.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId,10),l=a.find(e=>e.workOrderMilestoneId===n);let c;const i=e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/doUpdateWorkOrderMilestone",e.currentTarget,e=>{s(e),e.success&&c()})};cityssm.openHtmlModal("workOrder-editMilestone",{onshow:e=>{e.querySelector("#milestoneEdit--workOrderId").value=o,e.querySelector("#milestoneEdit--workOrderMilestoneId").value=l.workOrderMilestoneId.toString();const t=e.querySelector("#milestoneEdit--workOrderMilestoneTypeId");let s=!1;for(const e of exports.workOrderMilestoneTypes){const o=document.createElement("option");o.value=e.workOrderMilestoneTypeId.toString(),o.textContent=e.workOrderMilestoneType,e.workOrderMilestoneTypeId===l.workOrderMilestoneTypeId&&(o.selected=!0,s=!0),t.append(o)}if(!s&&l.workOrderMilestoneTypeId){const e=document.createElement("option");e.value=l.workOrderMilestoneTypeId.toString(),e.textContent=l.workOrderMilestoneType,e.selected=!0,t.append(e)}e.querySelector("#milestoneEdit--workOrderMilestoneDateString").value=l.workOrderMilestoneDateString,l.workOrderMilestoneTime&&(e.querySelector("#milestoneEdit--workOrderMilestoneTimeString").value=l.workOrderMilestoneTimeString),e.querySelector("#milestoneEdit--workOrderMilestoneDescription").value=l.workOrderMilestoneDescription},onshown:(t,o)=>{c=o,bulmaJS.toggleHtmlClipped(),e.initializeDatePickers(t),e.initializeTimePickers(t),t.querySelector("form").addEventListener("submit",i)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},i=()=>{const e=document.querySelector("#panel--milestones"),t=e.querySelectorAll(".panel-block");for(const e of t)e.remove();for(const t of a){const o=document.createElement("div");o.className="panel-block is-block container--milestone",o.dataset.workOrderMilestoneId=t.workOrderMilestoneId.toString(),o.innerHTML='
'+(t.workOrderMilestoneCompletionDate?'':'')+'
'+(t.workOrderMilestoneTypeId?""+cityssm.escapeHTML(t.workOrderMilestoneType)+"
":"")+t.workOrderMilestoneDateString+(t.workOrderMilestoneTime?" "+t.workOrderMilestoneTimeString:"")+'
'+cityssm.escapeHTML(t.workOrderMilestoneDescription)+'
',t.workOrderMilestoneCompletionDate?o.querySelector(".button--reopenMilestone").addEventListener("click",n):(o.querySelector(".button--editMilestone").addEventListener("click",c),o.querySelector(".button--completeMilestone").addEventListener("click",r)),o.querySelector(".button--deleteMilestone").addEventListener("click",l),e.append(o)}bulmaJS.init(e)};i(),document.querySelector("#button--addMilestone").addEventListener("click",()=>{let r,a;const n=e=>{e.preventDefault();const o=cityssm.dateToString(new Date),n=()=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderMilestone",e.currentTarget,e=>{s(e),e.success&&a()})};r.querySelector("#milestoneAdd--workOrderMilestoneDateString").value{e.querySelector("#milestoneAdd--workOrderId").value=o;const t=e.querySelector("#milestoneAdd--workOrderMilestoneTypeId");for(const e of exports.workOrderMilestoneTypes){const o=document.createElement("option");o.value=e.workOrderMilestoneTypeId.toString(),o.textContent=e.workOrderMilestoneType,t.append(o)}e.querySelector("#milestoneAdd--workOrderMilestoneDateString").valueAsDate=new Date},onshown:(t,o)=>{r=t,a=o,e.initializeDatePickers(t),e.initializeTimePickers(t),bulmaJS.toggleHtmlClipped(),t.querySelector("form").addEventListener("submit",n)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})})}})(); \ No newline at end of file +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,o=document.querySelector("#workOrderEdit--workOrderId").value,r=""===o,s=document.querySelector("#form--workOrderEdit");let a;if(e.initializeDatePickers(s.querySelector("#workOrderEdit--workOrderOpenDateString").closest(".field")),e.initializeUnlockFieldButtons(s),s.addEventListener("submit",e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/"+(r?"doCreateWorkOrder":"doUpdateWorkOrder"),e.currentTarget,e=>{e.success?r?window.location.href=t+"/workOrders/"+e.workOrderId+"/edit":bulmaJS.alert({message:"Work Order Updated Successfully",contextualColorName:"success"}):bulmaJS.alert({title:"Error Updating Work Order",message:e.errorMessage,contextualColorName:"danger"})})}),!r){const e=()=>{cityssm.postJSON(t+"/workOrders/doCloseWorkOrder",{workOrderId:o},e=>{e.success?window.location.href=t+"/workOrders/"+o:bulmaJS.alert({title:"Error Closing Work Order",message:e.errorMessage,contextualColorName:"danger"})})};document.querySelector("#button--closeWorkOrder").addEventListener("click",()=>{a.some(e=>!e.workOrderMilestoneCompletionDate)?bulmaJS.confirm({title:"Close Work Order with Outstanding Milestones",message:"Are you sure you want to close this work order with outstanding milestones?",contextualColorName:"danger",okButton:{text:"Yes, Close Work Order",callbackFunction:e}}):bulmaJS.confirm({title:"Close Work Order",message:"Are you sure you want to close this work order?",contextualColorName:"info",okButton:{text:"Yes, Close Work Order",callbackFunction:e}})});const r=()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrder",{workOrderId:o},e=>{e.success?window.location.href=t+"/workOrders":bulmaJS.alert({title:"Error Deleting Work Order",message:e.errorMessage,contextualColorName:"danger"})})};document.querySelector("#button--deleteWorkOrder").addEventListener("click",e=>{e.preventDefault(),bulmaJS.confirm({title:"Delete Work Order",message:"Are you sure you want to delete this work order?",contextualColorName:"warning",okButton:{text:"Yes, Delete Work Order",callbackFunction:r}})})}if(!r){let r=exports.workOrderLots;delete exports.workOrderLots;let s=exports.workOrderLotOccupancies;delete exports.workOrderLotOccupancies;const a=e=>{const r=e.currentTarget.closest(".container--lotOccupancy").dataset.lotOccupancyId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" "+exports.aliases.occupancy+" Relationship",message:"Are you sure you want to remove the relationship to this "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupancy.toLowerCase()+" record from this work order? Note that the record will remain.",contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderLotOccupancy",{workOrderId:o,lotOccupancyId:r},e=>{e.success?(s=e.workOrderLotOccupancies,m()):bulmaJS.alert({title:"Error Deleting Relationship",message:e.errorMessage,contextualColorName:"danger"})})}}})},n=(e,s)=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderLot",{workOrderId:o,lotId:e},e=>{e.success?(r=e.workOrderLots,m()):bulmaJS.alert({title:"Error Adding "+exports.aliases.lot,message:e.errorMessage,contextualColorName:"danger"}),s&&s(e.success)})},l=(e,r)=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderLotOccupancy",{workOrderId:o,lotOccupancyId:e},e=>{e.success?(s=e.workOrderLotOccupancies,m()):bulmaJS.alert({title:"Error Adding "+exports.aliases.occupancy,message:e.errorMessage,contextualColorName:"danger"}),r&&r(e.success)})},c=e=>{const t=e.currentTarget.dataset.lotId;n(t)},i=()=>{const e=document.querySelector("#container--lotOccupancies");if(document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent=s.length.toString(),0===s.length)return void(e.innerHTML='

There are no '+exports.aliases.occupancies.toLowerCase()+" associated with this work order.

");e.innerHTML='
'+exports.aliases.occupancy+" Type"+exports.aliases.lot+"Start DateEnd Date"+exports.aliases.occupants+'
';const o=cityssm.dateToString(new Date);for(const n of s){const s=document.createElement("tr");s.className="container--lotOccupancy",s.dataset.lotOccupancyId=n.lotOccupancyId.toString();const l=!(n.occupancyEndDate&&n.occupancyEndDateStringn.lotId===e.lotId);s.innerHTML=''+(l?'':'')+''+cityssm.escapeHTML(n.occupancyType)+"",n.lotId?s.insertAdjacentHTML("beforeend",""+cityssm.escapeHTML(n.lotName)+(i?"":' ')+""):s.insertAdjacentHTML("beforeend",'(No '+exports.aliases.lot+")"),s.insertAdjacentHTML("beforeend",""+n.occupancyStartDateString+""+(n.occupancyEndDate?n.occupancyEndDateString:'(No End Date)')+""+(0===n.lotOccupancyOccupants.length?'(No '+cityssm.escapeHTML(exports.aliases.occupants)+")":cityssm.escapeHTML(n.lotOccupancyOccupants[0].occupantName)+(n.lotOccupancyOccupants.length>1?" plus "+(n.lotOccupancyOccupants.length-1):""))+''),n.lotId&&!i&&s.querySelector(".button--addLot").addEventListener("click",c),s.querySelector(".button--deleteLotOccupancy").addEventListener("click",a),e.querySelector("tbody").append(s)}},d=e=>{const s=e.currentTarget.closest(".container--lot").dataset.lotId;bulmaJS.confirm({title:"Delete "+exports.aliases.lot+" "+exports.aliases.occupancy+" Relationship",message:"Are you sure you want to remove the relationship to this "+exports.aliases.lot.toLowerCase()+" "+exports.aliases.occupancy.toLowerCase()+" record from this work order? Note that the record will remain.",contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderLot",{workOrderId:o,lotId:s},e=>{e.success?(r=e.workOrderLots,m()):bulmaJS.alert({title:"Error Deleting Relationship",message:e.errorMessage,contextualColorName:"danger"})})}}})},u=()=>{const e=document.querySelector("#container--lots");if(document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent=r.length.toString(),0!==r.length){e.innerHTML='
'+exports.aliases.lot+""+exports.aliases.map+""+exports.aliases.lot+' TypeStatus
';for(const o of r){const r=document.createElement("tr");r.className="container--lot",r.dataset.lotId=o.lotId.toString(),r.innerHTML=''+cityssm.escapeHTML(o.lotName)+""+cityssm.escapeHTML(o.mapName)+""+cityssm.escapeHTML(o.lotType)+""+cityssm.escapeHTML(o.lotStatus)+'',r.querySelector(".button--deleteLot").addEventListener("click",d),e.querySelector("tbody").append(r)}}else e.innerHTML='

There are no '+exports.aliases.lots.toLowerCase()+" associated with this work order.

"},m=()=>{i(),u()};m(),document.querySelector("#button--addLotOccupancy").addEventListener("click",()=>{let r,s;const a=e=>{const t=e.currentTarget.closest("tr"),o=t.dataset.lotOccupancyId;l(o,e=>{e&&t.remove()})},n=e=>{e&&e.preventDefault(),s.innerHTML='


Searching...

',cityssm.postJSON(t+"/lotOccupancies/doSearchLotOccupancies",r,e=>{if(0!==e.lotOccupancies.length){s.innerHTML='
'+exports.aliases.occupancy+" Type"+exports.aliases.lot+"Start DateEnd Date"+exports.aliases.occupants+"
";for(const t of e.lotOccupancies){const e=document.createElement("tr");e.className="container--lotOccupancy",e.dataset.lotOccupancyId=t.lotOccupancyId.toString(),e.innerHTML=''+cityssm.escapeHTML(t.occupancyType)+"",t.lotId?e.insertAdjacentHTML("beforeend",""+cityssm.escapeHTML(t.lotName)+""):e.insertAdjacentHTML("beforeend",'(No '+exports.aliases.lot+")"),e.insertAdjacentHTML("beforeend",""+t.occupancyStartDateString+""+(t.occupancyEndDate?t.occupancyEndDateString:'(No End Date)')+""+(0===t.lotOccupancyOccupants.length?'(No '+cityssm.escapeHTML(exports.aliases.occupants)+")":cityssm.escapeHTML(t.lotOccupancyOccupants[0].occupantName)+(t.lotOccupancyOccupants.length>1?" plus "+(t.lotOccupancyOccupants.length-1):""))+""),e.querySelector(".button--addLotOccupancy").addEventListener("click",a),s.querySelector("tbody").append(e)}}else s.innerHTML='

There are no records that meet the search criteria.

'})};cityssm.openHtmlModal("workOrder-addLotOccupancy",{onshow:t=>{e.populateAliases(t),r=t.querySelector("form"),s=t.querySelector("#resultsContainer--lotOccupancyAdd"),t.querySelector("#lotOccupancySearch--notWorkOrderId").value=o,t.querySelector("#lotOccupancySearch--occupancyEffectiveDateString").value=document.querySelector("#workOrderEdit--workOrderOpenDateString").value,n()},onshown:e=>{bulmaJS.toggleHtmlClipped(),e.querySelector("#lotOccupancySearch--occupantName").addEventListener("change",n),e.querySelector("#lotOccupancySearch--lotName").addEventListener("change",n),r.addEventListener("submit",n)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}),document.querySelector("#button--addLot").addEventListener("click",()=>{let r,s;const a=e=>{const t=e.currentTarget.closest("tr"),o=t.dataset.lotId;n(o,e=>{e&&t.remove()})},l=e=>{e&&e.preventDefault(),s.innerHTML='


Searching...

',cityssm.postJSON(t+"/lots/doSearchLots",r,e=>{if(0!==e.lots.length){s.innerHTML='
'+exports.aliases.lot+""+exports.aliases.map+""+exports.aliases.lot+" TypeStatus
";for(const t of e.lots){const e=document.createElement("tr");e.className="container--lot",e.dataset.lotId=t.lotId.toString(),e.innerHTML=''+cityssm.escapeHTML(t.lotName)+""+cityssm.escapeHTML(t.mapName)+""+cityssm.escapeHTML(t.lotType)+""+cityssm.escapeHTML(t.lotStatus)+"",e.querySelector(".button--addLot").addEventListener("click",a),s.querySelector("tbody").append(e)}}else s.innerHTML='

There are no records that meet the search criteria.

'})};cityssm.openHtmlModal("workOrder-addLot",{onshow:t=>{e.populateAliases(t),r=t.querySelector("form"),s=t.querySelector("#resultsContainer--lotAdd"),t.querySelector("#lotSearch--notWorkOrderId").value=o;const a=t.querySelector("#lotSearch--lotStatusId");for(const e of exports.lotStatuses){const t=document.createElement("option");t.value=e.lotStatusId.toString(),t.textContent=e.lotStatus,a.append(t)}l()},onshown:e=>{bulmaJS.toggleHtmlClipped(),e.querySelector("#lotSearch--lotName").addEventListener("change",l),e.querySelector("#lotSearch--lotStatusId").addEventListener("change",l),r.addEventListener("submit",l)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})})}let n=exports.workOrderComments;delete exports.workOrderComments;const l=r=>{const s=Number.parseInt(r.currentTarget.closest("tr").dataset.workOrderCommentId,10),a=n.find(e=>e.workOrderCommentId===s);let l,c;console.log(n);const d=e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/doUpdateWorkOrderComment",l,e=>{e.success?(n=e.workOrderComments,c(),i()):bulmaJS.alert({title:"Error Updating Comment",message:e.errorMessage,contextualColorName:"danger"})})};cityssm.openHtmlModal("workOrder-editComment",{onshow:e=>{e.querySelector("#workOrderCommentEdit--workOrderId").value=o,e.querySelector("#workOrderCommentEdit--workOrderCommentId").value=s.toString(),e.querySelector("#workOrderCommentEdit--workOrderComment").value=a.workOrderComment,e.querySelector("#workOrderCommentEdit--workOrderCommentDateString").value=a.workOrderCommentDateString,e.querySelector("#workOrderCommentEdit--workOrderCommentTimeString").value=a.workOrderCommentTimeString},onshown:(t,o)=>{bulmaJS.toggleHtmlClipped(),e.initializeDatePickers(t),e.initializeTimePickers(t),t.querySelector("#workOrderCommentEdit--workOrderComment").focus(),(l=t.querySelector("form")).addEventListener("submit",d),c=o},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},c=e=>{const r=Number.parseInt(e.currentTarget.closest("tr").dataset.workOrderCommentId,10);bulmaJS.confirm({title:"Remove Comment?",message:"Are you sure you want to remove this comment?",okButton:{text:"Yes, Remove Comment",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderComment",{workOrderId:o,workOrderCommentId:r},e=>{e.success?(n=e.workOrderComments,i()):bulmaJS.alert({title:"Error Removing Comment",message:e.errorMessage,contextualColorName:"danger"})})}},contextualColorName:"warning"})},i=()=>{const e=document.querySelector("#container--workOrderComments");if(0===n.length)return void(e.innerHTML='

There are no comments to display.

');const t=document.createElement("table");t.className="table is-fullwidth is-striped is-hoverable",t.innerHTML='CommentorComment DateCommentOptions';for(const e of n){const o=document.createElement("tr");o.dataset.workOrderCommentId=e.workOrderCommentId.toString(),o.innerHTML=""+cityssm.escapeHTML(e.recordCreate_userName)+""+e.workOrderCommentDateString+(0===e.workOrderCommentTime?"":" "+e.workOrderCommentTimeString)+""+cityssm.escapeHTML(e.workOrderComment)+'
',o.querySelector(".button--edit").addEventListener("click",l),o.querySelector(".button--delete").addEventListener("click",c),t.querySelector("tbody").append(o)}e.innerHTML="",e.append(t)},d=()=>{let r;const s=e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/doAddWorkOrderComment",e.currentTarget,e=>{e.success&&(n=e.workOrderComments,i(),r())})};cityssm.openHtmlModal("workOrder-addComment",{onshow(t){e.populateAliases(t),t.querySelector("#workOrderCommentAdd--workOrderId").value=o,t.querySelector("form").addEventListener("submit",s)},onshown(e,t){bulmaJS.toggleHtmlClipped(),r=t,e.querySelector("#workOrderCommentAdd--workOrderComment").focus()},onremoved(){bulmaJS.toggleHtmlClipped(),document.querySelector("#workOrderComments--add").focus()}})};if(r||(document.querySelector("#workOrderComments--add").addEventListener("click",d),i()),!r){a=exports.workOrderMilestones,delete exports.workOrderMilestones;const r=e=>{e.success?(a=e.workOrderMilestones,i()):bulmaJS.alert({title:"Error Reopening Milestone",message:e.errorMessage,contextualColorName:"danger"})},s=e=>{e.preventDefault();const s=cityssm.dateToString(new Date),n=Number.parseInt(e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId,10),l=a.find(e=>e.workOrderMilestoneId===n);bulmaJS.confirm({title:"Complete Milestone",message:"Are you sure you want to complete this milestone?"+(l.workOrderMilestoneDateString>s?"
Note that this milestone is expected to be completed in the future.":""),messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Complete Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doCompleteWorkOrderMilestone",{workOrderId:o,workOrderMilestoneId:n},r)}}})},n=e=>{e.preventDefault();const s=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Reopen Milestone",message:"Are you sure you want to remove the completion status from this milestone, and reopen it?",contextualColorName:"warning",okButton:{text:"Yes, Reopen Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doReopenWorkOrderMilestone",{workOrderId:o,workOrderMilestoneId:s},r)}}})},l=e=>{e.preventDefault();const s=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Delete Milestone",message:"Are you sure you want to delete this milestone?",contextualColorName:"warning",okButton:{text:"Yes, Delete Milestone",callbackFunction:()=>{cityssm.postJSON(t+"/workOrders/doDeleteWorkOrderMilestone",{workOrderMilestoneId:s,workOrderId:o},r)}}})},c=s=>{s.preventDefault();const n=Number.parseInt(s.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId,10),l=a.find(e=>e.workOrderMilestoneId===n);let c;const i=e=>{e.preventDefault(),cityssm.postJSON(t+"/workOrders/doUpdateWorkOrderMilestone",e.currentTarget,e=>{r(e),e.success&&c()})};cityssm.openHtmlModal("workOrder-editMilestone",{onshow:e=>{e.querySelector("#milestoneEdit--workOrderId").value=o,e.querySelector("#milestoneEdit--workOrderMilestoneId").value=l.workOrderMilestoneId.toString();const t=e.querySelector("#milestoneEdit--workOrderMilestoneTypeId");let r=!1;for(const e of exports.workOrderMilestoneTypes){const o=document.createElement("option");o.value=e.workOrderMilestoneTypeId.toString(),o.textContent=e.workOrderMilestoneType,e.workOrderMilestoneTypeId===l.workOrderMilestoneTypeId&&(o.selected=!0,r=!0),t.append(o)}if(!r&&l.workOrderMilestoneTypeId){const e=document.createElement("option");e.value=l.workOrderMilestoneTypeId.toString(),e.textContent=l.workOrderMilestoneType,e.selected=!0,t.append(e)}e.querySelector("#milestoneEdit--workOrderMilestoneDateString").value=l.workOrderMilestoneDateString,l.workOrderMilestoneTime&&(e.querySelector("#milestoneEdit--workOrderMilestoneTimeString").value=l.workOrderMilestoneTimeString),e.querySelector("#milestoneEdit--workOrderMilestoneDescription").value=l.workOrderMilestoneDescription},onshown:(t,o)=>{c=o,bulmaJS.toggleHtmlClipped(),e.initializeDatePickers(t),e.initializeTimePickers(t),t.querySelector("form").addEventListener("submit",i)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})},i=()=>{const e=document.querySelector("#panel--milestones"),t=e.querySelectorAll(".panel-block");for(const e of t)e.remove();for(const t of a){const o=document.createElement("div");o.className="panel-block is-block container--milestone",o.dataset.workOrderMilestoneId=t.workOrderMilestoneId.toString(),o.innerHTML='
'+(t.workOrderMilestoneCompletionDate?'':'')+'
'+(t.workOrderMilestoneTypeId?""+cityssm.escapeHTML(t.workOrderMilestoneType)+"
":"")+t.workOrderMilestoneDateString+(t.workOrderMilestoneTime?" "+t.workOrderMilestoneTimeString:"")+'
'+cityssm.escapeHTML(t.workOrderMilestoneDescription)+'
',t.workOrderMilestoneCompletionDate?o.querySelector(".button--reopenMilestone").addEventListener("click",n):(o.querySelector(".button--editMilestone").addEventListener("click",c),o.querySelector(".button--completeMilestone").addEventListener("click",s)),o.querySelector(".button--deleteMilestone").addEventListener("click",l),e.append(o)}bulmaJS.init(e)};i(),document.querySelector("#button--addMilestone").addEventListener("click",()=>{let s,a;const n=e=>{e.preventDefault();const o=cityssm.dateToString(new Date),n=()=>{cityssm.postJSON(t+"/workOrders/doAddWorkOrderMilestone",e.currentTarget,e=>{r(e),e.success&&a()})};s.querySelector("#milestoneAdd--workOrderMilestoneDateString").value{e.querySelector("#milestoneAdd--workOrderId").value=o;const t=e.querySelector("#milestoneAdd--workOrderMilestoneTypeId");for(const e of exports.workOrderMilestoneTypes){const o=document.createElement("option");o.value=e.workOrderMilestoneTypeId.toString(),o.textContent=e.workOrderMilestoneType,t.append(o)}e.querySelector("#milestoneAdd--workOrderMilestoneDateString").valueAsDate=new Date},onshown:(t,o)=>{s=t,a=o,e.initializeDatePickers(t),e.initializeTimePickers(t),bulmaJS.toggleHtmlClipped(),t.querySelector("form").addEventListener("submit",n)},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})})}})(); \ No newline at end of file diff --git a/routes/workOrders.js b/routes/workOrders.js index e10aeba3..91696c92 100644 --- a/routes/workOrders.js +++ b/routes/workOrders.js @@ -17,6 +17,9 @@ import handler_doAddWorkOrderLotOccupancy from "../handlers/workOrders-post/doAd import handler_doDeleteWorkOrderLotOccupancy from "../handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.js"; import handler_doAddWorkOrderLot from "../handlers/workOrders-post/doAddWorkOrderLot.js"; import handler_doDeleteWorkOrderLot from "../handlers/workOrders-post/doDeleteWorkOrderLot.js"; +import handler_doAddWorkOrderComment from "../handlers/workOrders-post/doAddWorkOrderComment.js"; +import handler_doUpdateWorkOrderComment from "../handlers/workOrders-post/doUpdateWorkOrderComment.js"; +import handler_doDeleteWorkOrderComment from "../handlers/workOrders-post/doDeleteWorkOrderComment.js"; import handler_doAddWorkOrderMilestone from "../handlers/workOrders-post/doAddWorkOrderMilestone.js"; import handler_doUpdateWorkOrderMilestone from "../handlers/workOrders-post/doUpdateWorkOrderMilestone.js"; import handler_doCompleteWorkOrderMilestone from "../handlers/workOrders-post/doCompleteWorkOrderMilestone.js"; @@ -40,6 +43,9 @@ router.post("/doAddWorkOrderLotOccupancy", permissionHandlers.updatePostHandler, router.post("/doDeleteWorkOrderLotOccupancy", permissionHandlers.updatePostHandler, handler_doDeleteWorkOrderLotOccupancy); router.post("/doAddWorkOrderLot", permissionHandlers.updatePostHandler, handler_doAddWorkOrderLot); router.post("/doDeleteWorkOrderLot", permissionHandlers.updatePostHandler, handler_doDeleteWorkOrderLot); +router.post("/doAddWorkOrderComment", permissionHandlers.updatePostHandler, handler_doAddWorkOrderComment); +router.post("/doUpdateWorkOrderComment", permissionHandlers.updatePostHandler, handler_doUpdateWorkOrderComment); +router.post("/doDeleteWorkOrderComment", permissionHandlers.updatePostHandler, handler_doDeleteWorkOrderComment); router.post("/doAddWorkOrderMilestone", permissionHandlers.updatePostHandler, handler_doAddWorkOrderMilestone); router.post("/doUpdateWorkOrderMilestone", permissionHandlers.updatePostHandler, handler_doUpdateWorkOrderMilestone); router.post("/doCompleteWorkOrderMilestone", permissionHandlers.updatePostHandler, handler_doCompleteWorkOrderMilestone); diff --git a/routes/workOrders.ts b/routes/workOrders.ts index c6e941e8..93eea2be 100644 --- a/routes/workOrders.ts +++ b/routes/workOrders.ts @@ -27,6 +27,10 @@ import handler_doDeleteWorkOrderLotOccupancy from "../handlers/workOrders-post/d import handler_doAddWorkOrderLot from "../handlers/workOrders-post/doAddWorkOrderLot.js"; import handler_doDeleteWorkOrderLot from "../handlers/workOrders-post/doDeleteWorkOrderLot.js"; +import handler_doAddWorkOrderComment from "../handlers/workOrders-post/doAddWorkOrderComment.js"; +import handler_doUpdateWorkOrderComment from "../handlers/workOrders-post/doUpdateWorkOrderComment.js"; +import handler_doDeleteWorkOrderComment from "../handlers/workOrders-post/doDeleteWorkOrderComment.js"; + import handler_doAddWorkOrderMilestone from "../handlers/workOrders-post/doAddWorkOrderMilestone.js"; import handler_doUpdateWorkOrderMilestone from "../handlers/workOrders-post/doUpdateWorkOrderMilestone.js"; import handler_doCompleteWorkOrderMilestone from "../handlers/workOrders-post/doCompleteWorkOrderMilestone.js"; @@ -123,6 +127,26 @@ router.post( handler_doDeleteWorkOrderLot ); +// Comments + +router.post( + "/doAddWorkOrderComment", + permissionHandlers.updatePostHandler, + handler_doAddWorkOrderComment +); + +router.post( + "/doUpdateWorkOrderComment", + permissionHandlers.updatePostHandler, + handler_doUpdateWorkOrderComment +); + +router.post( + "/doDeleteWorkOrderComment", + permissionHandlers.updatePostHandler, + handler_doDeleteWorkOrderComment +); + // Milestones router.post( diff --git a/views/workOrder-edit.ejs b/views/workOrder-edit.ejs index cba7a6ef..12ef6e98 100644 --- a/views/workOrder-edit.ejs +++ b/views/workOrder-edit.ejs @@ -193,6 +193,31 @@
<% } %> + + <% if (!isCreate) { %> +
+
+
+
+
+

+ Comments +

+
+
+
+
+ +
+
+
+
+
+
+ <% } %>
<% if (!isCreate) { %>
diff --git a/views/workOrder-view.ejs b/views/workOrder-view.ejs index a0b93868..f912ab73 100644 --- a/views/workOrder-view.ejs +++ b/views/workOrder-view.ejs @@ -208,6 +208,29 @@ <% if (workOrder.workOrderComments.length > 0) { %>

Work Order Comments

+
+ + + + + + + + + + <% for (const workOrderComment of workOrder.workOrderComments) { %> + + + + + + <% } %> + +
CommentorComment DateComment
<%= workOrderComment.recordCreate_userName %> + <%= workOrderComment.workOrderCommentDateString %> + <%= (workOrderComment.workOrderCommentTime === 0 ? "" : workOrderComment.workOrderCommentTimeString) %> + <%= workOrderComment.workOrderComment %>
+
<% } %>