milestone type maintenance

deepsource-autofix-76c6eb20
Dan Gowans 2022-09-15 12:57:19 -04:00
parent 00e89f44e8
commit 326cac8717
37 changed files with 995 additions and 4 deletions

View File

@ -1,11 +1,13 @@
import { getLotOccupantTypes, getLotStatuses, getWorkOrderTypes } from "../../helpers/functions.cache.js";
import { getLotOccupantTypes, getLotStatuses, getWorkOrderMilestoneTypes, getWorkOrderTypes } from "../../helpers/functions.cache.js";
export const handler = (_request, response) => {
const workOrderTypes = getWorkOrderTypes();
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
const lotStatuses = getLotStatuses();
const lotOccupantTypes = getLotOccupantTypes();
response.render("admin-tables", {
headTitle: "Config Table Management",
workOrderTypes,
workOrderMilestoneTypes,
lotStatuses,
lotOccupantTypes
});

View File

@ -3,17 +3,20 @@ import type { RequestHandler } from "express";
import {
getLotOccupantTypes,
getLotStatuses,
getWorkOrderMilestoneTypes,
getWorkOrderTypes
} from "../../helpers/functions.cache.js";
export const handler: RequestHandler = (_request, response) => {
const workOrderTypes = getWorkOrderTypes();
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
const lotStatuses = getLotStatuses();
const lotOccupantTypes = getLotOccupantTypes();
response.render("admin-tables", {
headTitle: "Config Table Management",
workOrderTypes,
workOrderMilestoneTypes,
lotStatuses,
lotOccupantTypes
});

View File

@ -0,0 +1,3 @@
import type { RequestHandler } from "express";
export declare const handler: RequestHandler;
export default handler;

View File

@ -0,0 +1,12 @@
import { addWorkOrderMilestoneType } from "../../helpers/lotOccupancyDB/addWorkOrderMilestoneType.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler = async (request, response) => {
const workOrderMilestoneTypeId = addWorkOrderMilestoneType(request.body, request.session);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success: true,
workOrderMilestoneTypeId,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,19 @@
import type { RequestHandler } from "express";
import { addWorkOrderMilestoneType } from "../../helpers/lotOccupancyDB/addWorkOrderMilestoneType.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler: RequestHandler = async (request, response) => {
const workOrderMilestoneTypeId = addWorkOrderMilestoneType(request.body, request.session);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success: true,
workOrderMilestoneTypeId,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,3 @@
import type { RequestHandler } from "express";
export declare const handler: RequestHandler;
export default handler;

View File

@ -0,0 +1,11 @@
import { deleteWorkOrderMilestoneType } from "../../helpers/lotOccupancyDB/deleteWorkOrderMilestoneType.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler = async (request, response) => {
const success = deleteWorkOrderMilestoneType(request.body.workOrderMilestoneTypeId, request.session);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,21 @@
import type { RequestHandler } from "express";
import { deleteWorkOrderMilestoneType } from "../../helpers/lotOccupancyDB/deleteWorkOrderMilestoneType.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler: RequestHandler = async (request, response) => {
const success = deleteWorkOrderMilestoneType(
request.body.workOrderMilestoneTypeId,
request.session
);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,3 @@
import type { RequestHandler } from "express";
export declare const handler: RequestHandler;
export default handler;

View File

@ -0,0 +1,11 @@
import { moveWorkOrderMilestoneTypeDown } from "../../helpers/lotOccupancyDB/moveWorkOrderMilestoneTypeDown.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler = async (request, response) => {
const success = moveWorkOrderMilestoneTypeDown(request.body.workOrderMilestoneTypeId);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,18 @@
import type { RequestHandler } from "express";
import { moveWorkOrderMilestoneTypeDown } from "../../helpers/lotOccupancyDB/moveWorkOrderMilestoneTypeDown.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler: RequestHandler = async (request, response) => {
const success = moveWorkOrderMilestoneTypeDown(request.body.workOrderMilestoneTypeId);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,3 @@
import type { RequestHandler } from "express";
export declare const handler: RequestHandler;
export default handler;

View File

@ -0,0 +1,11 @@
import { moveWorkOrderMilestoneTypeUp } from "../../helpers/lotOccupancyDB/moveWorkOrderMilestoneTypeUp.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler = async (request, response) => {
const success = moveWorkOrderMilestoneTypeUp(request.body.workOrderMilestoneTypeId);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,18 @@
import type { RequestHandler } from "express";
import { moveWorkOrderMilestoneTypeUp } from "../../helpers/lotOccupancyDB/moveWorkOrderMilestoneTypeUp.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler: RequestHandler = async (request, response) => {
const success = moveWorkOrderMilestoneTypeUp(request.body.workOrderMilestoneTypeId);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,3 @@
import type { RequestHandler } from "express";
export declare const handler: RequestHandler;
export default handler;

View File

@ -0,0 +1,11 @@
import { updateWorkOrderMilestoneType } from "../../helpers/lotOccupancyDB/updateWorkOrderMilestoneType.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler = async (request, response) => {
const success = updateWorkOrderMilestoneType(request.body, request.session);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,18 @@
import type { RequestHandler } from "express";
import { updateWorkOrderMilestoneType } from "../../helpers/lotOccupancyDB/updateWorkOrderMilestoneType.js";
import { getWorkOrderMilestoneTypes } from "../../helpers/functions.cache.js";
export const handler: RequestHandler = async (request, response) => {
const success = updateWorkOrderMilestoneType(request.body, request.session);
const workOrderMilestoneTypes = getWorkOrderMilestoneTypes();
response.json({
success,
workOrderMilestoneTypes
});
};
export default handler;

View File

@ -0,0 +1,3 @@
import type * as recordTypes from "../../types/recordTypes";
export declare const deleteWorkOrderMilestoneType: (workOrderMilestoneTypeId: number | string, requestSession: recordTypes.PartialSession) => boolean;
export default deleteWorkOrderMilestoneType;

View File

@ -0,0 +1,17 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearWorkOrderMilestoneTypesCache } from "../functions.cache.js";
export const deleteWorkOrderMilestoneType = (workOrderMilestoneTypeId, requestSession) => {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare("update WorkOrderMilestoneTypes" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderMilestoneTypeId = ?")
.run(requestSession.user.userName, rightNowMillis, workOrderMilestoneTypeId);
database.close();
clearWorkOrderMilestoneTypesCache();
return result.changes > 0;
};
export default deleteWorkOrderMilestoneType;

View File

@ -0,0 +1,33 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearWorkOrderMilestoneTypesCache } from "../functions.cache.js";
import type * as recordTypes from "../../types/recordTypes";
export const deleteWorkOrderMilestoneType = (
workOrderMilestoneTypeId: number | string,
requestSession: recordTypes.PartialSession
): boolean => {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare(
"update WorkOrderMilestoneTypes" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderMilestoneTypeId = ?"
)
.run(requestSession.user.userName, rightNowMillis, workOrderMilestoneTypeId);
database.close();
clearWorkOrderMilestoneTypesCache();
return result.changes > 0;
};
export default deleteWorkOrderMilestoneType;

View File

@ -12,7 +12,7 @@ export const getWorkOrderMilestoneTypes = () => {
for (const workOrderMilestoneType of workOrderMilestoneTypes) {
if (workOrderMilestoneType.orderNumber !== expectedOrderNumber) {
database
.prepare("update WorkOrdeMilestoneTypes" +
.prepare("update WorkOrderMilestoneTypes" +
" set orderNumber = ?" +
" where workOrderMilestoneTypeId = ?")
.run(expectedOrderNumber, workOrderMilestoneType.workOrderMilestoneTypeId);

View File

@ -22,7 +22,7 @@ export const getWorkOrderMilestoneTypes = (): recordTypes.WorkOrderMilestoneType
if (workOrderMilestoneType.orderNumber !== expectedOrderNumber) {
database
.prepare(
"update WorkOrdeMilestoneTypes" +
"update WorkOrderMilestoneTypes" +
" set orderNumber = ?" +
" where workOrderMilestoneTypeId = ?"
)

View File

@ -0,0 +1,2 @@
export declare const moveWorkOrderMilestoneTypeDown: (workOrderMilestoneTypeId: number | string) => boolean;
export default moveWorkOrderMilestoneTypeDown;

View File

@ -0,0 +1,26 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearWorkOrderMilestoneTypesCache } from "../functions.cache.js";
export const moveWorkOrderMilestoneTypeDown = (workOrderMilestoneTypeId) => {
const database = sqlite(databasePath);
const currentOrderNumber = database
.prepare("select orderNumber" +
" from WorkOrderMilestoneTypes" +
" where workOrderMilestoneTypeId = ?")
.get(workOrderMilestoneTypeId).orderNumber;
database
.prepare("update WorkOrderMilestoneTypes" +
" set orderNumber = orderNumber - 1" +
" where recordDelete_timeMillis is null" +
" and orderNumber = ? + 1")
.run(currentOrderNumber);
const result = database
.prepare("update WorkOrderMilestoneTypes" +
" set orderNumber = ? + 1" +
" where workOrderMilestoneTypeId = ?")
.run(currentOrderNumber, workOrderMilestoneTypeId);
database.close();
clearWorkOrderMilestoneTypesCache();
return result.changes > 0;
};
export default moveWorkOrderMilestoneTypeDown;

View File

@ -0,0 +1,44 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearWorkOrderMilestoneTypesCache } from "../functions.cache.js";
export const moveWorkOrderMilestoneTypeDown = (
workOrderMilestoneTypeId: number | string
): boolean => {
const database = sqlite(databasePath);
const currentOrderNumber: number = database
.prepare(
"select orderNumber" +
" from WorkOrderMilestoneTypes" +
" where workOrderMilestoneTypeId = ?"
)
.get(workOrderMilestoneTypeId).orderNumber;
database
.prepare(
"update WorkOrderMilestoneTypes" +
" set orderNumber = orderNumber - 1" +
" where recordDelete_timeMillis is null" +
" and orderNumber = ? + 1"
)
.run(currentOrderNumber);
const result = database
.prepare(
"update WorkOrderMilestoneTypes" +
" set orderNumber = ? + 1" +
" where workOrderMilestoneTypeId = ?"
)
.run(currentOrderNumber, workOrderMilestoneTypeId);
database.close();
clearWorkOrderMilestoneTypesCache();
return result.changes > 0;
};
export default moveWorkOrderMilestoneTypeDown;

View File

@ -0,0 +1,2 @@
export declare const moveWorkOrderMilestoneTypeUp: (workOrderMilestoneTypeId: number | string) => boolean;
export default moveWorkOrderMilestoneTypeUp;

View File

@ -0,0 +1,30 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearWorkOrderMilestoneTypesCache } from "../functions.cache.js";
export const moveWorkOrderMilestoneTypeUp = (workOrderMilestoneTypeId) => {
const database = sqlite(databasePath);
const currentOrderNumber = database
.prepare("select orderNumber" +
" from WorkOrderMilestoneTypes" +
" where workOrderMilestoneTypeId = ?")
.get(workOrderMilestoneTypeId).orderNumber;
if (currentOrderNumber <= 0) {
database.close();
return true;
}
database
.prepare("update WorkOrderMilestoneTypes" +
" set orderNumber = orderNumber + 1" +
" where recordDelete_timeMillis is null" +
" and orderNumber = ? - 1")
.run(currentOrderNumber);
const result = database
.prepare("update WorkOrderMilestoneTypes" +
" set orderNumber = ? - 1" +
" where workOrderMilestoneTypeId = ?")
.run(currentOrderNumber, workOrderMilestoneTypeId);
database.close();
clearWorkOrderMilestoneTypesCache();
return result.changes > 0;
};
export default moveWorkOrderMilestoneTypeUp;

View File

@ -0,0 +1,49 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearWorkOrderMilestoneTypesCache } from "../functions.cache.js";
export const moveWorkOrderMilestoneTypeUp = (
workOrderMilestoneTypeId: number | string
): boolean => {
const database = sqlite(databasePath);
const currentOrderNumber: number = database
.prepare(
"select orderNumber" +
" from WorkOrderMilestoneTypes" +
" where workOrderMilestoneTypeId = ?"
)
.get(workOrderMilestoneTypeId).orderNumber;
if (currentOrderNumber <= 0) {
database.close();
return true;
}
database
.prepare(
"update WorkOrderMilestoneTypes" +
" set orderNumber = orderNumber + 1" +
" where recordDelete_timeMillis is null" +
" and orderNumber = ? - 1"
)
.run(currentOrderNumber);
const result = database
.prepare(
"update WorkOrderMilestoneTypes" +
" set orderNumber = ? - 1" +
" where workOrderMilestoneTypeId = ?"
)
.run(currentOrderNumber, workOrderMilestoneTypeId);
database.close();
clearWorkOrderMilestoneTypesCache();
return result.changes > 0;
};
export default moveWorkOrderMilestoneTypeUp;

View File

@ -0,0 +1,7 @@
import type * as recordTypes from "../../types/recordTypes";
interface UpdateWorkOrderMilestoneTypeForm {
workOrderMilestoneTypeId: number | string;
workOrderMilestoneType: string;
}
export declare const updateWorkOrderMilestoneType: (workOrderMilestoneTypeForm: UpdateWorkOrderMilestoneTypeForm, requestSession: recordTypes.PartialSession) => boolean;
export default updateWorkOrderMilestoneType;

View File

@ -0,0 +1,19 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearWorkOrderMilestoneTypesCache } from "../functions.cache.js";
export const updateWorkOrderMilestoneType = (workOrderMilestoneTypeForm, requestSession) => {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare("update WorkOrderMilestoneTypes" +
" set workOrderMilestoneType = ?," +
" recordUpdate_userName = ?," +
" recordUpdate_timeMillis = ?" +
" where workOrderMilestoneTypeId = ?" +
" and recordDelete_timeMillis is null")
.run(workOrderMilestoneTypeForm.workOrderMilestoneType, requestSession.user.userName, rightNowMillis, workOrderMilestoneTypeForm.workOrderMilestoneTypeId);
database.close();
clearWorkOrderMilestoneTypesCache();
return result.changes > 0;
};
export default updateWorkOrderMilestoneType;

View File

@ -0,0 +1,45 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { clearWorkOrderMilestoneTypesCache } from "../functions.cache.js";
import type * as recordTypes from "../../types/recordTypes";
interface UpdateWorkOrderMilestoneTypeForm {
workOrderMilestoneTypeId: number | string;
workOrderMilestoneType: string;
}
export const updateWorkOrderMilestoneType = (
workOrderMilestoneTypeForm: UpdateWorkOrderMilestoneTypeForm,
requestSession: recordTypes.PartialSession
): boolean => {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare(
"update WorkOrderMilestoneTypes" +
" set workOrderMilestoneType = ?," +
" recordUpdate_userName = ?," +
" recordUpdate_timeMillis = ?" +
" where workOrderMilestoneTypeId = ?" +
" and recordDelete_timeMillis is null"
)
.run(
workOrderMilestoneTypeForm.workOrderMilestoneType,
requestSession.user.userName,
rightNowMillis,
workOrderMilestoneTypeForm.workOrderMilestoneTypeId
);
database.close();
clearWorkOrderMilestoneTypesCache();
return result.changes > 0;
};
export default updateWorkOrderMilestoneType;

View File

@ -194,6 +194,198 @@ Object.defineProperty(exports, "__esModule", { value: true });
});
});
renderWorkOrderTypes();
let workOrderMilestoneTypes = exports.workOrderMilestoneTypes;
delete exports.workOrderMilestoneTypes;
const updateWorkOrderMilestoneType = (submitEvent) => {
submitEvent.preventDefault();
cityssm.postJSON(urlPrefix + "/admin/doUpdateWorkOrderMilestoneType", submitEvent.currentTarget, (responseJSON) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
bulmaJS.alert({
message: "Work Order Milestone Type Updated Successfully",
contextualColorName: "success"
});
}
else {
bulmaJS.alert({
title: "Error Updating Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
});
};
const deleteWorkOrderMilestoneType = (clickEvent) => {
const tableRowElement = clickEvent.currentTarget.closest("tr");
const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId;
const doDelete = () => {
cityssm.postJSON(urlPrefix + "/admin/doDeleteWorkOrderMilestoneType", {
workOrderMilestoneTypeId
}, (responseJSON) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
if (workOrderMilestoneTypes.length === 0) {
renderWorkOrderMilestoneTypes();
}
else {
tableRowElement.remove();
}
bulmaJS.alert({
message: "Work Order Milestone Type Deleted Successfully",
contextualColorName: "success"
});
}
else {
bulmaJS.alert({
title: "Error Deleting Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
});
};
bulmaJS.confirm({
title: "Delete Work Order Milestone Type",
message: "Are you sure you want to delete this work order milestone type?<br />" +
"Note that no work orders will be removed.",
messageIsHtml: true,
contextualColorName: "warning",
okButton: {
text: "Yes, Delete Work Order Milestone Type",
callbackFunction: doDelete
}
});
};
const moveWorkOrderMilestoneTypeUp = (clickEvent) => {
const tableRowElement = clickEvent.currentTarget.closest("tr");
const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId;
cityssm.postJSON(urlPrefix + "/admin/doMoveWorkOrderMilestoneTypeUp", {
workOrderMilestoneTypeId
}, (responseJSON) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
renderWorkOrderMilestoneTypes();
}
else {
bulmaJS.alert({
title: "Error Moving Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
});
};
const moveWorkOrderMilestoneTypeDown = (clickEvent) => {
const tableRowElement = clickEvent.currentTarget.closest("tr");
const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId;
cityssm.postJSON(urlPrefix + "/admin/doMoveWorkOrderMilestoneTypeDown", {
workOrderMilestoneTypeId
}, (responseJSON) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
renderWorkOrderMilestoneTypes();
}
else {
bulmaJS.alert({
title: "Error Moving Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
});
};
const renderWorkOrderMilestoneTypes = () => {
const containerElement = document.querySelector("#container--workOrderMilestoneTypes");
if (workOrderMilestoneTypes.length === 0) {
containerElement.innerHTML =
"<tr>" +
'<td colspan="2">' +
'<div class="message is-warning">' +
'<p class="message-body">There are no active work order milestone types.</p>' +
"</div>" +
"</td>" +
"</tr>";
return;
}
containerElement.innerHTML = "";
for (const workOrderMilestoneType of workOrderMilestoneTypes) {
const tableRowElement = document.createElement("tr");
tableRowElement.dataset.workOrderMilestoneTypeId =
workOrderMilestoneType.workOrderMilestoneTypeId.toString();
tableRowElement.innerHTML =
"<td>" +
"<form>" +
'<input name="workOrderMilestoneTypeId" type="hidden" value="' +
workOrderMilestoneType.workOrderMilestoneTypeId.toString() +
'" />' +
('<div class="field has-addons">' +
'<div class="control">' +
'<input class="input" name="workOrderMilestoneType" type="text" value="' +
cityssm.escapeHTML(workOrderMilestoneType.workOrderMilestoneType) +
'" maxlength="100" required />' +
"</div>" +
'<div class="control">' +
'<button class="button is-success" type="submit"><i class="fas fa-save" aria-hidden="true"></i></button>' +
"</div>" +
"</div>") +
"</form>" +
"</td>" +
'<td class="is-nowrap">' +
'<div class="field is-grouped">' +
'<div class="control">' +
('<div class="field has-addons">' +
'<div class="control">' +
'<button class="button button--moveWorkOrderMilestoneTypeUp" data-tooltip="Move Up" type="button" aria-label="Move Up"><i class="fas fa-arrow-up" aria-hidden="true"></i></button>' +
"</div>" +
'<div class="control">' +
'<button class="button button--moveWorkOrderMilestoneTypeDown" data-tooltip="Move Down" type="button" aria-label="Move Down"><i class="fas fa-arrow-down" aria-hidden="true"></i></button>' +
"</div>" +
"</div>") +
"</div>" +
'<div class="control">' +
'<button class="button is-danger is-light button--deleteWorkOrderMilestoneType" data-tooltip="Delete Mielstone Type" type="button" aria-label="Delete Milestone Type">' +
'<i class="fas fa-trash" aria-hidden="true"></i>' +
"</button>" +
"</div>" +
"</div>" +
"</td>";
tableRowElement
.querySelector("form")
.addEventListener("submit", updateWorkOrderMilestoneType);
tableRowElement
.querySelector(".button--moveWorkOrderMilestoneTypeUp")
.addEventListener("click", moveWorkOrderMilestoneTypeUp);
tableRowElement
.querySelector(".button--moveWorkOrderMilestoneTypeDown")
.addEventListener("click", moveWorkOrderMilestoneTypeDown);
tableRowElement
.querySelector(".button--deleteWorkOrderMilestoneType")
.addEventListener("click", deleteWorkOrderMilestoneType);
containerElement.append(tableRowElement);
}
};
document
.querySelector("#form--addWorkOrderMilestoneType")
.addEventListener("submit", (submitEvent) => {
submitEvent.preventDefault();
const formElement = submitEvent.currentTarget;
cityssm.postJSON(urlPrefix + "/admin/doAddWorkOrderMilestoneType", formElement, (responseJSON) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
renderWorkOrderMilestoneTypes();
formElement.reset();
formElement.querySelector("input").focus();
}
else {
bulmaJS.alert({
title: "Error Adding Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
});
});
renderWorkOrderMilestoneTypes();
let lotStatuses = exports.lotStatuses;
delete exports.lotStatuses;
const updateLotStatus = (submitEvent) => {

View File

@ -280,6 +280,274 @@ declare const bulmaJS: BulmaJS;
renderWorkOrderTypes();
/*
* Work Order Milestone Types
*/
let workOrderMilestoneTypes: recordTypes.WorkOrderMilestoneType[] = exports.workOrderMilestoneTypes;
delete exports.workOrderMilestoneTypes;
const updateWorkOrderMilestoneType = (submitEvent: SubmitEvent) => {
submitEvent.preventDefault();
cityssm.postJSON(
urlPrefix + "/admin/doUpdateWorkOrderMilestoneType",
submitEvent.currentTarget,
(responseJSON: {
success: boolean;
errorMessage?: string;
workOrderMilestoneTypes?: recordTypes.WorkOrderMilestoneType[];
}) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
bulmaJS.alert({
message: "Work Order Milestone Type Updated Successfully",
contextualColorName: "success"
});
} else {
bulmaJS.alert({
title: "Error Updating Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
}
);
};
const deleteWorkOrderMilestoneType = (clickEvent: Event) => {
const tableRowElement = (
clickEvent.currentTarget as HTMLElement
).closest("tr");
const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId;
const doDelete = () => {
cityssm.postJSON(
urlPrefix + "/admin/doDeleteWorkOrderMilestoneType",
{
workOrderMilestoneTypeId
},
(responseJSON: {
success: boolean;
errorMessage?: string;
workOrderMilestoneTypes?: recordTypes.WorkOrderMilestoneType[];
}) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
if (workOrderMilestoneTypes.length === 0) {
renderWorkOrderMilestoneTypes();
} else {
tableRowElement.remove();
}
bulmaJS.alert({
message: "Work Order Milestone Type Deleted Successfully",
contextualColorName: "success"
});
} else {
bulmaJS.alert({
title: "Error Deleting Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
}
);
};
bulmaJS.confirm({
title: "Delete Work Order Milestone Type",
message:
"Are you sure you want to delete this work order milestone type?<br />" +
"Note that no work orders will be removed.",
messageIsHtml: true,
contextualColorName: "warning",
okButton: {
text: "Yes, Delete Work Order Milestone Type",
callbackFunction: doDelete
}
});
};
const moveWorkOrderMilestoneTypeUp = (clickEvent: Event) => {
const tableRowElement = (
clickEvent.currentTarget as HTMLElement
).closest("tr");
const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId;
cityssm.postJSON(
urlPrefix + "/admin/doMoveWorkOrderMilestoneTypeUp",
{
workOrderMilestoneTypeId
},
(responseJSON: {
success: boolean;
errorMessage?: string;
workOrderMilestoneTypes?: recordTypes.WorkOrderMilestoneType[];
}) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
renderWorkOrderMilestoneTypes();
} else {
bulmaJS.alert({
title: "Error Moving Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
}
);
};
const moveWorkOrderMilestoneTypeDown = (clickEvent: Event) => {
const tableRowElement = (
clickEvent.currentTarget as HTMLElement
).closest("tr");
const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId;
cityssm.postJSON(
urlPrefix + "/admin/doMoveWorkOrderMilestoneTypeDown",
{
workOrderMilestoneTypeId
},
(responseJSON: {
success: boolean;
errorMessage?: string;
workOrderMilestoneTypes?: recordTypes.WorkOrderMilestoneType[];
}) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
renderWorkOrderMilestoneTypes();
} else {
bulmaJS.alert({
title: "Error Moving Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
}
);
};
const renderWorkOrderMilestoneTypes = () => {
const containerElement = document.querySelector(
"#container--workOrderMilestoneTypes"
) as HTMLTableSectionElement;
if (workOrderMilestoneTypes.length === 0) {
containerElement.innerHTML =
"<tr>" +
'<td colspan="2">' +
'<div class="message is-warning">' +
'<p class="message-body">There are no active work order milestone types.</p>' +
"</div>" +
"</td>" +
"</tr>";
return;
}
containerElement.innerHTML = "";
for (const workOrderMilestoneType of workOrderMilestoneTypes) {
const tableRowElement = document.createElement("tr");
tableRowElement.dataset.workOrderMilestoneTypeId =
workOrderMilestoneType.workOrderMilestoneTypeId.toString();
tableRowElement.innerHTML =
"<td>" +
"<form>" +
'<input name="workOrderMilestoneTypeId" type="hidden" value="' +
workOrderMilestoneType.workOrderMilestoneTypeId.toString() +
'" />' +
('<div class="field has-addons">' +
'<div class="control">' +
'<input class="input" name="workOrderMilestoneType" type="text" value="' +
cityssm.escapeHTML(workOrderMilestoneType.workOrderMilestoneType) +
'" maxlength="100" required />' +
"</div>" +
'<div class="control">' +
'<button class="button is-success" type="submit"><i class="fas fa-save" aria-hidden="true"></i></button>' +
"</div>" +
"</div>") +
"</form>" +
"</td>" +
'<td class="is-nowrap">' +
'<div class="field is-grouped">' +
'<div class="control">' +
('<div class="field has-addons">' +
'<div class="control">' +
'<button class="button button--moveWorkOrderMilestoneTypeUp" data-tooltip="Move Up" type="button" aria-label="Move Up"><i class="fas fa-arrow-up" aria-hidden="true"></i></button>' +
"</div>" +
'<div class="control">' +
'<button class="button button--moveWorkOrderMilestoneTypeDown" data-tooltip="Move Down" type="button" aria-label="Move Down"><i class="fas fa-arrow-down" aria-hidden="true"></i></button>' +
"</div>" +
"</div>") +
"</div>" +
'<div class="control">' +
'<button class="button is-danger is-light button--deleteWorkOrderMilestoneType" data-tooltip="Delete Mielstone Type" type="button" aria-label="Delete Milestone Type">' +
'<i class="fas fa-trash" aria-hidden="true"></i>' +
"</button>" +
"</div>" +
"</div>" +
"</td>";
tableRowElement
.querySelector("form")
.addEventListener("submit", updateWorkOrderMilestoneType);
tableRowElement
.querySelector(".button--moveWorkOrderMilestoneTypeUp")
.addEventListener("click", moveWorkOrderMilestoneTypeUp);
tableRowElement
.querySelector(".button--moveWorkOrderMilestoneTypeDown")
.addEventListener("click", moveWorkOrderMilestoneTypeDown);
tableRowElement
.querySelector(".button--deleteWorkOrderMilestoneType")
.addEventListener("click", deleteWorkOrderMilestoneType);
containerElement.append(tableRowElement);
}
};
document
.querySelector("#form--addWorkOrderMilestoneType")
.addEventListener("submit", (submitEvent: SubmitEvent) => {
submitEvent.preventDefault();
const formElement = submitEvent.currentTarget as HTMLFormElement;
cityssm.postJSON(
urlPrefix + "/admin/doAddWorkOrderMilestoneType",
formElement,
(responseJSON: {
success: boolean;
errorMessage?: string;
workOrderMilestoneTypes?: recordTypes.WorkOrderMilestoneType[];
}) => {
if (responseJSON.success) {
workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes;
renderWorkOrderMilestoneTypes();
formElement.reset();
formElement.querySelector("input").focus();
} else {
bulmaJS.alert({
title: "Error Adding Work Order Milestone Type",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
}
);
});
renderWorkOrderMilestoneTypes();
/*
* Lot Statuses
*/

File diff suppressed because one or more lines are too long

View File

@ -25,6 +25,11 @@ import handler_doUpdateWorkOrderType from "../handlers/admin-post/doUpdateWorkOr
import handler_doMoveWorkOrderTypeUp from "../handlers/admin-post/doMoveWorkOrderTypeUp.js";
import handler_doMoveWorkOrderTypeDown from "../handlers/admin-post/doMoveWorkOrderTypeDown.js";
import handler_doDeleteWorkOrderType from "../handlers/admin-post/doDeleteWorkOrderType.js";
import handler_doAddWorkOrderMilestoneType from "../handlers/admin-post/doAddWorkOrderMilestoneType.js";
import handler_doUpdateWorkOrderMilestoneType from "../handlers/admin-post/doUpdateWorkOrderMilestoneType.js";
import handler_doMoveWorkOrderMilestoneTypeUp from "../handlers/admin-post/doMoveWorkOrderMilestoneTypeUp.js";
import handler_doMoveWorkOrderMilestoneTypeDown from "../handlers/admin-post/doMoveWorkOrderMilestoneTypeDown.js";
import handler_doDeleteWorkOrderMilestoneType from "../handlers/admin-post/doDeleteWorkOrderMilestoneType.js";
import handler_doAddLotStatus from "../handlers/admin-post/doAddLotStatus.js";
import handler_doUpdateLotStatus from "../handlers/admin-post/doUpdateLotStatus.js";
import handler_doMoveLotStatusUp from "../handlers/admin-post/doMoveLotStatusUp.js";
@ -61,6 +66,11 @@ router.post("/doUpdateWorkOrderType", permissionHandlers.adminPostHandler, handl
router.post("/doMoveWorkOrderTypeUp", permissionHandlers.adminPostHandler, handler_doMoveWorkOrderTypeUp);
router.post("/doMoveWorkOrderTypeDown", permissionHandlers.adminPostHandler, handler_doMoveWorkOrderTypeDown);
router.post("/doDeleteWorkOrderType", permissionHandlers.adminPostHandler, handler_doDeleteWorkOrderType);
router.post("/doAddWorkOrderMilestoneType", permissionHandlers.adminPostHandler, handler_doAddWorkOrderMilestoneType);
router.post("/doUpdateWorkOrderMilestoneType", permissionHandlers.adminPostHandler, handler_doUpdateWorkOrderMilestoneType);
router.post("/doMoveWorkOrderMilestoneTypeUp", permissionHandlers.adminPostHandler, handler_doMoveWorkOrderMilestoneTypeUp);
router.post("/doMoveWorkOrderMilestoneTypeDown", permissionHandlers.adminPostHandler, handler_doMoveWorkOrderMilestoneTypeDown);
router.post("/doDeleteWorkOrderMilestoneType", permissionHandlers.adminPostHandler, handler_doDeleteWorkOrderMilestoneType);
router.post("/doAddLotStatus", permissionHandlers.adminPostHandler, handler_doAddLotStatus);
router.post("/doUpdateLotStatus", permissionHandlers.adminPostHandler, handler_doUpdateLotStatus);
router.post("/doMoveLotStatusUp", permissionHandlers.adminPostHandler, handler_doMoveLotStatusUp);

View File

@ -41,6 +41,12 @@ import handler_doMoveWorkOrderTypeUp from "../handlers/admin-post/doMoveWorkOrde
import handler_doMoveWorkOrderTypeDown from "../handlers/admin-post/doMoveWorkOrderTypeDown.js";
import handler_doDeleteWorkOrderType from "../handlers/admin-post/doDeleteWorkOrderType.js";
import handler_doAddWorkOrderMilestoneType from "../handlers/admin-post/doAddWorkOrderMilestoneType.js";
import handler_doUpdateWorkOrderMilestoneType from "../handlers/admin-post/doUpdateWorkOrderMilestoneType.js";
import handler_doMoveWorkOrderMilestoneTypeUp from "../handlers/admin-post/doMoveWorkOrderMilestoneTypeUp.js";
import handler_doMoveWorkOrderMilestoneTypeDown from "../handlers/admin-post/doMoveWorkOrderMilestoneTypeDown.js";
import handler_doDeleteWorkOrderMilestoneType from "../handlers/admin-post/doDeleteWorkOrderMilestoneType.js";
import handler_doAddLotStatus from "../handlers/admin-post/doAddLotStatus.js";
import handler_doUpdateLotStatus from "../handlers/admin-post/doUpdateLotStatus.js";
import handler_doMoveLotStatusUp from "../handlers/admin-post/doMoveLotStatusUp.js";
@ -208,6 +214,37 @@ router.post(
permissionHandlers.adminPostHandler,
handler_doDeleteWorkOrderType
);
// Config Tables - Work Order Milestone Types
router.post(
"/doAddWorkOrderMilestoneType",
permissionHandlers.adminPostHandler,
handler_doAddWorkOrderMilestoneType
);
router.post(
"/doUpdateWorkOrderMilestoneType",
permissionHandlers.adminPostHandler,
handler_doUpdateWorkOrderMilestoneType
);
router.post(
"/doMoveWorkOrderMilestoneTypeUp",
permissionHandlers.adminPostHandler,
handler_doMoveWorkOrderMilestoneTypeUp
);
router.post(
"/doMoveWorkOrderMilestoneTypeDown",
permissionHandlers.adminPostHandler,
handler_doMoveWorkOrderMilestoneTypeDown
);
router.post(
"/doDeleteWorkOrderMilestoneType",
permissionHandlers.adminPostHandler,
handler_doDeleteWorkOrderMilestoneType
);
// Config Tables - Lot Statuses

View File

@ -35,6 +35,12 @@
<span>Work Order Types</span>
</a>
</li>
<li>
<a href="#tab--workOrderMilestoneTypes">
<span class="icon is-small"><i class="fas fa-table" aria-hidden="true"></i></span>
<span>Work Order Milestone Types</span>
</a>
</li>
<li>
<a href="#tab--lotStatuses">
<span class="icon is-small"><i class="fas fa-table" aria-hidden="true"></i></span>
@ -80,6 +86,36 @@
<tbody id="container--workOrderTypes"></tbody>
</table>
</div>
<div class="is-hidden" id="tab--workOrderMilestoneTypes">
<h2 class="title is-4">Work Order Milestone Types</h2>
<table class="table is-striped is-hoverable">
<thead>
<tr>
<th>Work Order Milestone Type</th>
<th class="has-text-centered has-width-1">Options</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2">
<form id="form--addWorkOrderMilestoneType">
<div class="field has-addons">
<div class="control is-expanded">
<input class="input" name="workOrderMilestoneType" type="text" maxlength="100" placeholder="New Milestone Type" required />
</div>
<div class="control">
<button class="button is-success" data-tooltip="Add Work Order Milestone Type" type="submit" aria-label="Add Work Order Milestone Type">
<i class="fas fa-plus" aria-hidden="true"></i>
</button>
</div>
</div>
</form>
</td>
</tr>
</tbody>
<tbody id="container--workOrderMilestoneTypes"></tbody>
</table>
</div>
<div class="is-hidden" id="tab--lotStatuses">
<h2 class="title is-4"><%= configFunctions.getProperty("aliases.lot") %> Statuses</h2>
<table class="table is-striped is-hoverable">
@ -148,6 +184,7 @@
<script>
exports.workOrderTypes = <%- JSON.stringify(workOrderTypes) %>;
exports.workOrderMilestoneTypes = <%- JSON.stringify(workOrderMilestoneTypes) %>;
exports.lotStatuses = <%- JSON.stringify(lotStatuses) %>;
exports.lotOccupantTypes = <%- JSON.stringify(lotOccupantTypes) %>;
</script>