work order development
parent
c4e6324112
commit
ab87f933c7
|
|
@ -1,3 +1,4 @@
|
|||
import { getWorkOrderTypes } from "../../helpers/functions.cache.js";
|
||||
import * as configFunctions from "../../helpers/functions.config.js";
|
||||
import { getWorkOrder } from "../../helpers/lotOccupancyDB/getWorkOrder.js";
|
||||
export const handler = (request, response) => {
|
||||
|
|
@ -6,9 +7,16 @@ export const handler = (request, response) => {
|
|||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
|
||||
"/workOrders/?error=workOrderIdNotFound");
|
||||
}
|
||||
if (workOrder.workOrderCloseDate) {
|
||||
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") +
|
||||
"/workOrders/" + workOrder.workOrderId.toString() + "/?error=workOrderIsClosed");
|
||||
}
|
||||
const workOrderTypes = getWorkOrderTypes();
|
||||
response.render("workOrder-edit", {
|
||||
headTitle: "Work Order #" + workOrder.workOrderNumber,
|
||||
workOrder
|
||||
workOrder,
|
||||
isCreate: false,
|
||||
workOrderTypes
|
||||
});
|
||||
};
|
||||
export default handler;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { RequestHandler } from "express";
|
||||
import { getWorkOrderTypes } from "../../helpers/functions.cache.js";
|
||||
|
||||
import * as configFunctions from "../../helpers/functions.config.js";
|
||||
|
||||
|
|
@ -14,9 +15,20 @@ export const handler: RequestHandler = (request, response) => {
|
|||
);
|
||||
}
|
||||
|
||||
if (workOrder.workOrderCloseDate) {
|
||||
return response.redirect(
|
||||
configFunctions.getProperty("reverseProxy.urlPrefix") +
|
||||
"/workOrders/" + workOrder.workOrderId.toString() + "/?error=workOrderIsClosed"
|
||||
);
|
||||
}
|
||||
|
||||
const workOrderTypes = getWorkOrderTypes();
|
||||
|
||||
response.render("workOrder-edit", {
|
||||
headTitle: "Work Order #" + workOrder.workOrderNumber,
|
||||
workOrder
|
||||
workOrder,
|
||||
isCreate: false,
|
||||
workOrderTypes
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
import type { RequestHandler } from "express";
|
||||
export declare const handler: RequestHandler;
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import { deleteWorkOrderLot } from "../../helpers/lotOccupancyDB/deleteWorkOrderLot.js";
|
||||
import { getLots } from "../../helpers/lotOccupancyDB/getLots.js";
|
||||
export const handler = async (request, response) => {
|
||||
const success = deleteWorkOrderLot(request.body.workOrderId, request.body.lotId, request.session);
|
||||
const workOrderLots = getLots({
|
||||
workOrderId: request.body.workOrderId
|
||||
}, {
|
||||
limit: -1,
|
||||
offset: 0
|
||||
}).lots;
|
||||
response.json({
|
||||
success,
|
||||
workOrderLots
|
||||
});
|
||||
};
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import type { RequestHandler } from "express";
|
||||
|
||||
import { deleteWorkOrderLot } from "../../helpers/lotOccupancyDB/deleteWorkOrderLot.js";
|
||||
import { getLots } from "../../helpers/lotOccupancyDB/getLots.js";
|
||||
|
||||
export const handler: RequestHandler = async (request, response) => {
|
||||
const success = deleteWorkOrderLot(
|
||||
request.body.workOrderId,
|
||||
request.body.lotId,
|
||||
request.session
|
||||
);
|
||||
|
||||
const workOrderLots = getLots(
|
||||
{
|
||||
workOrderId: request.body.workOrderId
|
||||
},
|
||||
{
|
||||
limit: -1,
|
||||
offset: 0
|
||||
}
|
||||
).lots;
|
||||
|
||||
response.json({
|
||||
success,
|
||||
workOrderLots
|
||||
});
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import type { RequestHandler } from "express";
|
||||
export declare const handler: RequestHandler;
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import { deleteWorkOrderLotOccupancy } from "../../helpers/lotOccupancyDB/deleteWorkOrderLotOccupancy.js";
|
||||
import { getLotOccupancies } from "../../helpers/lotOccupancyDB/getLotOccupancies.js";
|
||||
export const handler = async (request, response) => {
|
||||
const success = deleteWorkOrderLotOccupancy(request.body.workOrderId, request.body.lotOccupancyId, request.session);
|
||||
const workOrderLotOccupancies = getLotOccupancies({
|
||||
workOrderId: request.body.workOrderId
|
||||
}, {
|
||||
limit: -1,
|
||||
offset: 0,
|
||||
includeOccupants: true
|
||||
}).lotOccupancies;
|
||||
response.json({
|
||||
success,
|
||||
workOrderLotOccupancies
|
||||
});
|
||||
};
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import type { RequestHandler } from "express";
|
||||
|
||||
import { deleteWorkOrderLotOccupancy } from "../../helpers/lotOccupancyDB/deleteWorkOrderLotOccupancy.js";
|
||||
import { getLotOccupancies } from "../../helpers/lotOccupancyDB/getLotOccupancies.js";
|
||||
|
||||
export const handler: RequestHandler = async (request, response) => {
|
||||
const success = deleteWorkOrderLotOccupancy(
|
||||
request.body.workOrderId,
|
||||
request.body.lotOccupancyId,
|
||||
request.session
|
||||
);
|
||||
|
||||
const workOrderLotOccupancies = getLotOccupancies(
|
||||
{
|
||||
workOrderId: request.body.workOrderId
|
||||
},
|
||||
{
|
||||
limit: -1,
|
||||
offset: 0,
|
||||
includeOccupants: true
|
||||
}
|
||||
).lotOccupancies;
|
||||
|
||||
response.json({
|
||||
success,
|
||||
workOrderLotOccupancies
|
||||
});
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import type { RequestHandler } from "express";
|
||||
export declare const handler: RequestHandler;
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { reopenWorkOrder } from "../../helpers/lotOccupancyDB/reopenWorkOrder.js";
|
||||
export const handler = async (request, response) => {
|
||||
const success = reopenWorkOrder(request.body.workOrderId, request.session);
|
||||
response.json({
|
||||
success,
|
||||
workOrderId: request.body.workOrderId
|
||||
});
|
||||
};
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import type { RequestHandler } from "express";
|
||||
|
||||
import { reopenWorkOrder } from "../../helpers/lotOccupancyDB/reopenWorkOrder.js";
|
||||
|
||||
export const handler: RequestHandler = async (request, response) => {
|
||||
const success = reopenWorkOrder(request.body.workOrderId, request.session);
|
||||
|
||||
response.json({
|
||||
success,
|
||||
workOrderId: request.body.workOrderId
|
||||
});
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import type { RequestHandler } from "express";
|
||||
export declare const handler: RequestHandler;
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { updateWorkOrder } from "../../helpers/lotOccupancyDB/updateWorkOrder.js";
|
||||
export const handler = async (request, response) => {
|
||||
const success = updateWorkOrder(request.body, request.session);
|
||||
response.json({
|
||||
success,
|
||||
workOrderId: request.body.workOrderId
|
||||
});
|
||||
};
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import type { RequestHandler } from "express";
|
||||
|
||||
import { updateWorkOrder } from "../../helpers/lotOccupancyDB/updateWorkOrder.js";
|
||||
|
||||
export const handler: RequestHandler = async (request, response) => {
|
||||
const success = updateWorkOrder(request.body, request.session);
|
||||
|
||||
response.json({
|
||||
success,
|
||||
workOrderId: request.body.workOrderId
|
||||
});
|
||||
};
|
||||
|
||||
export default handler;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import type * as recordTypes from "../../types/recordTypes";
|
||||
export declare const deleteWorkOrderLot: (workOrderId: number | string, lotId: number | string, requestSession: recordTypes.PartialSession) => boolean;
|
||||
export default deleteWorkOrderLot;
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import sqlite from "better-sqlite3";
|
||||
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||
export const deleteWorkOrderLot = (workOrderId, lotId, requestSession) => {
|
||||
const database = sqlite(databasePath);
|
||||
const rightNowMillis = Date.now();
|
||||
const result = database
|
||||
.prepare("update WorkOrderLots" +
|
||||
" set recordDelete_userName = ?," +
|
||||
" recordDelete_timeMillis = ?" +
|
||||
" where workOrderId = ?" +
|
||||
" and lotId = ?")
|
||||
.run(requestSession.user.userName, rightNowMillis, workOrderId, lotId);
|
||||
database.close();
|
||||
return result.changes > 0;
|
||||
};
|
||||
export default deleteWorkOrderLot;
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import sqlite from "better-sqlite3";
|
||||
|
||||
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||
|
||||
import type * as recordTypes from "../../types/recordTypes";
|
||||
|
||||
export const deleteWorkOrderLot = (
|
||||
workOrderId: number | string,
|
||||
lotId: number | string,
|
||||
requestSession: recordTypes.PartialSession
|
||||
): boolean => {
|
||||
const database = sqlite(databasePath);
|
||||
|
||||
const rightNowMillis = Date.now();
|
||||
|
||||
const result = database
|
||||
.prepare(
|
||||
"update WorkOrderLots" +
|
||||
" set recordDelete_userName = ?," +
|
||||
" recordDelete_timeMillis = ?" +
|
||||
" where workOrderId = ?" +
|
||||
" and lotId = ?"
|
||||
)
|
||||
.run(requestSession.user.userName, rightNowMillis, workOrderId, lotId);
|
||||
|
||||
database.close();
|
||||
|
||||
return result.changes > 0;
|
||||
};
|
||||
|
||||
export default deleteWorkOrderLot;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import type * as recordTypes from "../../types/recordTypes";
|
||||
export declare const deleteWorkOrderLotOccupancy: (workOrderId: number | string, lotOccupancyId: number | string, requestSession: recordTypes.PartialSession) => boolean;
|
||||
export default deleteWorkOrderLotOccupancy;
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import sqlite from "better-sqlite3";
|
||||
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||
export const deleteWorkOrderLotOccupancy = (workOrderId, lotOccupancyId, requestSession) => {
|
||||
const database = sqlite(databasePath);
|
||||
const rightNowMillis = Date.now();
|
||||
const result = database
|
||||
.prepare("update WorkOrderLotOccupancies" +
|
||||
" set recordDelete_userName = ?," +
|
||||
" recordDelete_timeMillis = ?" +
|
||||
" where workOrderId = ?" +
|
||||
" and lotOccupancyId = ?")
|
||||
.run(requestSession.user.userName, rightNowMillis, workOrderId, lotOccupancyId);
|
||||
database.close();
|
||||
return result.changes > 0;
|
||||
};
|
||||
export default deleteWorkOrderLotOccupancy;
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import sqlite from "better-sqlite3";
|
||||
|
||||
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||
|
||||
import type * as recordTypes from "../../types/recordTypes";
|
||||
|
||||
export const deleteWorkOrderLotOccupancy = (
|
||||
workOrderId: number | string,
|
||||
lotOccupancyId: number | string,
|
||||
requestSession: recordTypes.PartialSession
|
||||
): boolean => {
|
||||
const database = sqlite(databasePath);
|
||||
|
||||
const rightNowMillis = Date.now();
|
||||
|
||||
const result = database
|
||||
.prepare(
|
||||
"update WorkOrderLotOccupancies" +
|
||||
" set recordDelete_userName = ?," +
|
||||
" recordDelete_timeMillis = ?" +
|
||||
" where workOrderId = ?" +
|
||||
" and lotOccupancyId = ?"
|
||||
)
|
||||
.run(requestSession.user.userName, rightNowMillis, workOrderId, lotOccupancyId);
|
||||
|
||||
database.close();
|
||||
|
||||
return result.changes > 0;
|
||||
};
|
||||
|
||||
export default deleteWorkOrderLotOccupancy;
|
||||
|
|
@ -0,0 +1 @@
|
|||
export {};
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
(() => {
|
||||
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
|
||||
const workOrderId = document.querySelector("#workOrderEdit--workOrderId").value;
|
||||
const isCreate = workOrderId === "";
|
||||
document
|
||||
.querySelector("#form--workOrderEdit")
|
||||
.addEventListener("submit", (submitEvent) => {
|
||||
submitEvent.preventDefault();
|
||||
cityssm.postJSON(urlPrefix +
|
||||
"/workOrders/" +
|
||||
(isCreate ? "doCreateWorkOrder" : "doUpdateWorkOrder"), submitEvent.currentTarget, (responseJSON) => {
|
||||
if (responseJSON.success) {
|
||||
if (isCreate) {
|
||||
window.location.href =
|
||||
urlPrefix +
|
||||
"/workOrders/" +
|
||||
responseJSON.workOrderId +
|
||||
"/edit";
|
||||
}
|
||||
else {
|
||||
bulmaJS.alert({
|
||||
message: "Work Order Updated Successfully",
|
||||
contextualColorName: "success"
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
bulmaJS.alert({
|
||||
title: "Error Updating Work Order",
|
||||
message: responseJSON.errorMessage,
|
||||
contextualColorName: "danger"
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
if (!isCreate) {
|
||||
let workOrderLots = exports.workOrderLots;
|
||||
delete exports.workOrderLots;
|
||||
let workOrderLotOccupancies = exports.workOrderLotOccupancies;
|
||||
delete exports.workOrderLotOccupancies;
|
||||
const deleteLotOccupancy = (clickEvent) => {
|
||||
const lotOccupancyId = clickEvent.currentTarget.closest(".container--lotOccupancy").dataset.lotOccupancyId;
|
||||
const doDelete = () => {
|
||||
cityssm.postJSON(urlPrefix + "/workOrders/doDeleteWorkOrderLotOccupancy", {
|
||||
workOrderId,
|
||||
lotOccupancyId
|
||||
}, (responseJSON) => {
|
||||
if (responseJSON.success) {
|
||||
workOrderLotOccupancies =
|
||||
responseJSON.workOrderLotOccupancies;
|
||||
renderRelatedLotsAndOccupancies();
|
||||
}
|
||||
else {
|
||||
bulmaJS.alert({
|
||||
title: "Error Deleting Relationship",
|
||||
message: responseJSON.errorMessage,
|
||||
contextualColorName: "danger"
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
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: doDelete
|
||||
}
|
||||
});
|
||||
};
|
||||
const renderRelatedOccupancies = () => {
|
||||
const occupanciesContainerElement = document.querySelector("#relatedTab--lotOccupancies");
|
||||
document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent = workOrderLotOccupancies.length.toString();
|
||||
if (workOrderLotOccupancies.length === 0) {
|
||||
occupanciesContainerElement.innerHTML =
|
||||
'<div class="message is-info">' +
|
||||
'<p class="message-body">There are no ' +
|
||||
exports.aliases.occupancies.toLowerCase() +
|
||||
" associated with this work order.</p>" +
|
||||
"</div>";
|
||||
return;
|
||||
}
|
||||
occupanciesContainerElement.innerHTML =
|
||||
'<table class="table is-fullwidth is-striped is-hoverable">' +
|
||||
"<thead>" +
|
||||
"<tr>" +
|
||||
'<th class="has-width-1"></th>' +
|
||||
("<th>" + exports.aliases.occupancy + " Type</th>") +
|
||||
("<th>" + exports.aliases.lot + "</th>") +
|
||||
"<th>Start Date</th>" +
|
||||
"<th>End Date</th>" +
|
||||
("<th>" + exports.aliases.occupants + "</th>") +
|
||||
'<th class="has-width-1"></th>' +
|
||||
"</tr>" +
|
||||
"</thead>" +
|
||||
"<tbody></tbody>" +
|
||||
"</table>";
|
||||
const currentDateString = cityssm.dateToString(new Date());
|
||||
for (const lotOccupancy of workOrderLotOccupancies) {
|
||||
const rowElement = document.createElement("tr");
|
||||
rowElement.className = "container--lotOccupancy";
|
||||
rowElement.dataset.lotOccupancyId =
|
||||
lotOccupancy.lotOccupancyId.toString();
|
||||
const isActive = !(lotOccupancy.occupancyEndDate &&
|
||||
lotOccupancy.occupancyEndDateString < currentDateString);
|
||||
rowElement.innerHTML =
|
||||
'<td class="has-text-centered">' +
|
||||
(isActive
|
||||
? '<i class="fas fa-play" title="Current ' +
|
||||
cityssm.escapeHTML(exports.aliases.occupancy) +
|
||||
'"></i>'
|
||||
: '<i class="fas fa-stop" title="Previous ' +
|
||||
cityssm.escapeHTML(exports.aliases.occupancy) +
|
||||
'"></i>') +
|
||||
"</td>" +
|
||||
("<td>" +
|
||||
'<a class="has-text-weight-bold" href="' +
|
||||
cityssm.escapeHTML(urlPrefix) +
|
||||
"/lotOccupancies/" +
|
||||
lotOccupancy.lotOccupancyId +
|
||||
'">' +
|
||||
cityssm.escapeHTML(lotOccupancy.occupancyType) +
|
||||
"</a>" +
|
||||
"</td>") +
|
||||
("<td>" +
|
||||
(lotOccupancy.lotId
|
||||
? cityssm.escapeHTML(lotOccupancy.lotName)
|
||||
: '<span class="has-text-grey">(No ' +
|
||||
exports.aliases.lot +
|
||||
")</span>") +
|
||||
"</td>") +
|
||||
("<td>" + lotOccupancy.occupancyStartDateString + "</td>") +
|
||||
("<td>" +
|
||||
(lotOccupancy.occupancyEndDate
|
||||
? lotOccupancy.occupancyEndDateString
|
||||
: '<span class="has-text-grey">(No End Date)</span>') +
|
||||
"</td>") +
|
||||
("<td>" +
|
||||
(lotOccupancy.lotOccupancyOccupants.length === 0
|
||||
? '<span class="has-text-grey">(No ' +
|
||||
cityssm.escapeHTML(exports.aliases.occupants) +
|
||||
")</span>"
|
||||
: cityssm.escapeHTML(lotOccupancy.lotOccupancyOccupants[0]
|
||||
.occupantName) +
|
||||
(lotOccupancy.lotOccupancyOccupants.length > 1
|
||||
? " plus " +
|
||||
(lotOccupancy.lotOccupancyOccupants.length -
|
||||
1)
|
||||
: "")) +
|
||||
"</td>") +
|
||||
("<td>" +
|
||||
'<button class="button is-small is-light is-danger button--deleteLotOccupancy" data-tooltip="Delete Relationship" type="button">' +
|
||||
'<i class="fas fa-trash" aria-hidden="true"></i>' +
|
||||
"</button>" +
|
||||
"</td>");
|
||||
rowElement
|
||||
.querySelector(".button--deleteLotOccupancy")
|
||||
.addEventListener("click", deleteLotOccupancy);
|
||||
occupanciesContainerElement
|
||||
.querySelector("tbody")
|
||||
.append(rowElement);
|
||||
}
|
||||
};
|
||||
const deleteLot = (clickEvent) => {
|
||||
const lotId = clickEvent.currentTarget.closest(".container--lot").dataset.lotId;
|
||||
const doDelete = () => {
|
||||
cityssm.postJSON(urlPrefix + "/workOrders/doDeleteWorkOrderLot", {
|
||||
workOrderId,
|
||||
lotId
|
||||
}, (responseJSON) => {
|
||||
if (responseJSON.success) {
|
||||
workOrderLots =
|
||||
responseJSON.workOrderLots;
|
||||
renderRelatedLotsAndOccupancies();
|
||||
}
|
||||
else {
|
||||
bulmaJS.alert({
|
||||
title: "Error Deleting Relationship",
|
||||
message: responseJSON.errorMessage,
|
||||
contextualColorName: "danger"
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
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: doDelete
|
||||
}
|
||||
});
|
||||
};
|
||||
const renderRelatedLots = () => {
|
||||
const lotsContainerElement = document.querySelector("#relatedTab--lots");
|
||||
document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent = workOrderLots.length.toString();
|
||||
if (workOrderLots.length === 0) {
|
||||
lotsContainerElement.innerHTML =
|
||||
'<div class="message is-info">' +
|
||||
'<p class="message-body">There are no ' +
|
||||
exports.aliases.lots.toLowerCase() +
|
||||
" associated with this work order.</p>" +
|
||||
"</div>";
|
||||
return;
|
||||
}
|
||||
lotsContainerElement.innerHTML =
|
||||
'<table class="table is-fullwidth is-striped is-hoverable">' +
|
||||
"<thead>" +
|
||||
"<tr>" +
|
||||
("<th>" + exports.aliases.lot + "</th>") +
|
||||
("<th>" + exports.aliases.map + "</th>") +
|
||||
("<th>" + exports.aliases.lot + " Type</th>") +
|
||||
"<th>Status</th>" +
|
||||
'<th class="has-width-1"></th>' +
|
||||
"</tr>" +
|
||||
"</thead>" +
|
||||
"<tbody></tbody>" +
|
||||
"</table>";
|
||||
for (const lot of workOrderLots) {
|
||||
const rowElement = document.createElement("tr");
|
||||
rowElement.className = "container--lot";
|
||||
rowElement.dataset.lotId = lot.lotId.toString();
|
||||
rowElement.innerHTML =
|
||||
"<td>" +
|
||||
'<a class="has-text-weight-bold" href="' +
|
||||
cityssm.escapeHTML(urlPrefix) +
|
||||
"/lots/" +
|
||||
lot.lotId +
|
||||
'">' +
|
||||
cityssm.escapeHTML(lot.lotName) +
|
||||
"</a>" +
|
||||
"</td>" +
|
||||
("<td>" + cityssm.escapeHTML(lot.mapName) + "</td>") +
|
||||
("<td>" + cityssm.escapeHTML(lot.lotType) + "</td>") +
|
||||
("<td>" + cityssm.escapeHTML(lot.lotStatus) + "</td>") +
|
||||
("<td>" +
|
||||
'<button class="button is-small is-light is-danger button--deleteLot" data-tooltip="Delete Relationship" type="button">' +
|
||||
'<i class="fas fa-trash" aria-hidden="true"></i>' +
|
||||
"</button>" +
|
||||
"</td>");
|
||||
rowElement
|
||||
.querySelector(".button--deleteLot")
|
||||
.addEventListener("click", deleteLot);
|
||||
lotsContainerElement.querySelector("tbody").append(rowElement);
|
||||
}
|
||||
};
|
||||
const renderRelatedLotsAndOccupancies = () => {
|
||||
renderRelatedOccupancies();
|
||||
renderRelatedLots();
|
||||
};
|
||||
renderRelatedLotsAndOccupancies();
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,376 @@
|
|||
/* eslint-disable unicorn/prefer-module */
|
||||
|
||||
import type { cityssmGlobal } from "@cityssm/bulma-webapp-js/src/types";
|
||||
import type { BulmaJS } from "@cityssm/bulma-js/types";
|
||||
import type * as recordTypes from "../types/recordTypes";
|
||||
|
||||
declare const cityssm: cityssmGlobal;
|
||||
declare const bulmaJS: BulmaJS;
|
||||
|
||||
(() => {
|
||||
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
|
||||
|
||||
const workOrderId = (
|
||||
document.querySelector(
|
||||
"#workOrderEdit--workOrderId"
|
||||
) as HTMLInputElement
|
||||
).value;
|
||||
|
||||
const isCreate = workOrderId === "";
|
||||
|
||||
document
|
||||
.querySelector("#form--workOrderEdit")
|
||||
.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"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
bulmaJS.alert({
|
||||
title: "Error Updating Work Order",
|
||||
message: responseJSON.errorMessage,
|
||||
contextualColorName: "danger"
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/*
|
||||
* Related Lots
|
||||
*/
|
||||
|
||||
if (!isCreate) {
|
||||
let workOrderLots: recordTypes.Lot[] = exports.workOrderLots;
|
||||
delete exports.workOrderLots;
|
||||
|
||||
let workOrderLotOccupancies: recordTypes.LotOccupancy[] =
|
||||
exports.workOrderLotOccupancies;
|
||||
delete exports.workOrderLotOccupancies;
|
||||
|
||||
const deleteLotOccupancy = (clickEvent: Event) => {
|
||||
const lotOccupancyId = (
|
||||
(clickEvent.currentTarget as HTMLElement).closest(
|
||||
".container--lotOccupancy"
|
||||
) as HTMLElement
|
||||
).dataset.lotOccupancyId;
|
||||
|
||||
const doDelete = () => {
|
||||
cityssm.postJSON(
|
||||
urlPrefix + "/workOrders/doDeleteWorkOrderLotOccupancy",
|
||||
{
|
||||
workOrderId,
|
||||
lotOccupancyId
|
||||
},
|
||||
(responseJSON: {
|
||||
success: boolean;
|
||||
errorMessage?: string;
|
||||
workOrderLotOccupancies?: recordTypes.LotOccupancy[];
|
||||
}) => {
|
||||
if (responseJSON.success) {
|
||||
workOrderLotOccupancies =
|
||||
responseJSON.workOrderLotOccupancies;
|
||||
renderRelatedLotsAndOccupancies();
|
||||
} else {
|
||||
bulmaJS.alert({
|
||||
title: "Error Deleting Relationship",
|
||||
message: responseJSON.errorMessage,
|
||||
contextualColorName: "danger"
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
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: doDelete
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const renderRelatedOccupancies = () => {
|
||||
const occupanciesContainerElement = document.querySelector(
|
||||
"#relatedTab--lotOccupancies"
|
||||
) as HTMLElement;
|
||||
|
||||
document.querySelector(
|
||||
".tabs a[href='#relatedTab--lotOccupancies'] .tag"
|
||||
).textContent = workOrderLotOccupancies.length.toString();
|
||||
|
||||
if (workOrderLotOccupancies.length === 0) {
|
||||
occupanciesContainerElement.innerHTML =
|
||||
'<div class="message is-info">' +
|
||||
'<p class="message-body">There are no ' +
|
||||
exports.aliases.occupancies.toLowerCase() +
|
||||
" associated with this work order.</p>" +
|
||||
"</div>";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
occupanciesContainerElement.innerHTML =
|
||||
'<table class="table is-fullwidth is-striped is-hoverable">' +
|
||||
"<thead>" +
|
||||
"<tr>" +
|
||||
'<th class="has-width-1"></th>' +
|
||||
("<th>" + exports.aliases.occupancy + " Type</th>") +
|
||||
("<th>" + exports.aliases.lot + "</th>") +
|
||||
"<th>Start Date</th>" +
|
||||
"<th>End Date</th>" +
|
||||
("<th>" + exports.aliases.occupants + "</th>") +
|
||||
'<th class="has-width-1"></th>' +
|
||||
"</tr>" +
|
||||
"</thead>" +
|
||||
"<tbody></tbody>" +
|
||||
"</table>";
|
||||
|
||||
const currentDateString = cityssm.dateToString(new Date());
|
||||
|
||||
for (const lotOccupancy of workOrderLotOccupancies) {
|
||||
const rowElement = document.createElement("tr");
|
||||
rowElement.className = "container--lotOccupancy";
|
||||
rowElement.dataset.lotOccupancyId =
|
||||
lotOccupancy.lotOccupancyId.toString();
|
||||
|
||||
const isActive = !(
|
||||
lotOccupancy.occupancyEndDate &&
|
||||
lotOccupancy.occupancyEndDateString < currentDateString
|
||||
);
|
||||
|
||||
rowElement.innerHTML =
|
||||
'<td class="has-text-centered">' +
|
||||
(isActive
|
||||
? '<i class="fas fa-play" title="Current ' +
|
||||
cityssm.escapeHTML(exports.aliases.occupancy) +
|
||||
'"></i>'
|
||||
: '<i class="fas fa-stop" title="Previous ' +
|
||||
cityssm.escapeHTML(exports.aliases.occupancy) +
|
||||
'"></i>') +
|
||||
"</td>" +
|
||||
("<td>" +
|
||||
'<a class="has-text-weight-bold" href="' +
|
||||
cityssm.escapeHTML(urlPrefix) +
|
||||
"/lotOccupancies/" +
|
||||
lotOccupancy.lotOccupancyId +
|
||||
'">' +
|
||||
cityssm.escapeHTML(lotOccupancy.occupancyType) +
|
||||
"</a>" +
|
||||
"</td>") +
|
||||
("<td>" +
|
||||
(lotOccupancy.lotId
|
||||
? cityssm.escapeHTML(lotOccupancy.lotName)
|
||||
: '<span class="has-text-grey">(No ' +
|
||||
exports.aliases.lot +
|
||||
")</span>") +
|
||||
"</td>") +
|
||||
("<td>" + lotOccupancy.occupancyStartDateString + "</td>") +
|
||||
("<td>" +
|
||||
(lotOccupancy.occupancyEndDate
|
||||
? lotOccupancy.occupancyEndDateString
|
||||
: '<span class="has-text-grey">(No End Date)</span>') +
|
||||
"</td>") +
|
||||
("<td>" +
|
||||
(lotOccupancy.lotOccupancyOccupants.length === 0
|
||||
? '<span class="has-text-grey">(No ' +
|
||||
cityssm.escapeHTML(exports.aliases.occupants) +
|
||||
")</span>"
|
||||
: cityssm.escapeHTML(
|
||||
lotOccupancy.lotOccupancyOccupants[0]
|
||||
.occupantName
|
||||
) +
|
||||
(lotOccupancy.lotOccupancyOccupants.length > 1
|
||||
? " plus " +
|
||||
(lotOccupancy.lotOccupancyOccupants.length -
|
||||
1)
|
||||
: "")) +
|
||||
"</td>") +
|
||||
("<td>" +
|
||||
'<button class="button is-small is-light is-danger button--deleteLotOccupancy" data-tooltip="Delete Relationship" type="button">' +
|
||||
'<i class="fas fa-trash" aria-hidden="true"></i>' +
|
||||
"</button>" +
|
||||
"</td>");
|
||||
|
||||
rowElement
|
||||
.querySelector(".button--deleteLotOccupancy")
|
||||
.addEventListener("click", deleteLotOccupancy);
|
||||
|
||||
occupanciesContainerElement
|
||||
.querySelector("tbody")
|
||||
.append(rowElement);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteLot = (clickEvent: Event) => {
|
||||
const lotId = (
|
||||
(clickEvent.currentTarget as HTMLElement).closest(
|
||||
".container--lot"
|
||||
) as HTMLElement
|
||||
).dataset.lotId;
|
||||
|
||||
const doDelete = () => {
|
||||
cityssm.postJSON(
|
||||
urlPrefix + "/workOrders/doDeleteWorkOrderLot",
|
||||
{
|
||||
workOrderId,
|
||||
lotId
|
||||
},
|
||||
(responseJSON: {
|
||||
success: boolean;
|
||||
errorMessage?: string;
|
||||
workOrderLots?: recordTypes.Lot[];
|
||||
}) => {
|
||||
if (responseJSON.success) {
|
||||
workOrderLots =
|
||||
responseJSON.workOrderLots;
|
||||
renderRelatedLotsAndOccupancies();
|
||||
} else {
|
||||
bulmaJS.alert({
|
||||
title: "Error Deleting Relationship",
|
||||
message: responseJSON.errorMessage,
|
||||
contextualColorName: "danger"
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
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: doDelete
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const renderRelatedLots = () => {
|
||||
const lotsContainerElement = document.querySelector(
|
||||
"#relatedTab--lots"
|
||||
) as HTMLElement;
|
||||
|
||||
document.querySelector(
|
||||
".tabs a[href='#relatedTab--lots'] .tag"
|
||||
).textContent = workOrderLots.length.toString();
|
||||
|
||||
if (workOrderLots.length === 0) {
|
||||
lotsContainerElement.innerHTML =
|
||||
'<div class="message is-info">' +
|
||||
'<p class="message-body">There are no ' +
|
||||
exports.aliases.lots.toLowerCase() +
|
||||
" associated with this work order.</p>" +
|
||||
"</div>";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
lotsContainerElement.innerHTML =
|
||||
'<table class="table is-fullwidth is-striped is-hoverable">' +
|
||||
"<thead>" +
|
||||
"<tr>" +
|
||||
("<th>" + exports.aliases.lot + "</th>") +
|
||||
("<th>" + exports.aliases.map + "</th>") +
|
||||
("<th>" + exports.aliases.lot + " Type</th>") +
|
||||
"<th>Status</th>" +
|
||||
'<th class="has-width-1"></th>' +
|
||||
"</tr>" +
|
||||
"</thead>" +
|
||||
"<tbody></tbody>" +
|
||||
"</table>";
|
||||
|
||||
for (const lot of workOrderLots) {
|
||||
const rowElement = document.createElement("tr");
|
||||
rowElement.className = "container--lot";
|
||||
|
||||
rowElement.dataset.lotId = lot.lotId.toString();
|
||||
|
||||
rowElement.innerHTML =
|
||||
"<td>" +
|
||||
'<a class="has-text-weight-bold" href="' +
|
||||
cityssm.escapeHTML(urlPrefix) +
|
||||
"/lots/" +
|
||||
lot.lotId +
|
||||
'">' +
|
||||
cityssm.escapeHTML(lot.lotName) +
|
||||
"</a>" +
|
||||
"</td>" +
|
||||
("<td>" + cityssm.escapeHTML(lot.mapName) + "</td>") +
|
||||
("<td>" + cityssm.escapeHTML(lot.lotType) + "</td>") +
|
||||
("<td>" + cityssm.escapeHTML(lot.lotStatus) + "</td>") +
|
||||
("<td>" +
|
||||
'<button class="button is-small is-light is-danger button--deleteLot" data-tooltip="Delete Relationship" type="button">' +
|
||||
'<i class="fas fa-trash" aria-hidden="true"></i>' +
|
||||
"</button>" +
|
||||
"</td>");
|
||||
|
||||
rowElement
|
||||
.querySelector(".button--deleteLot")
|
||||
.addEventListener("click", deleteLot);
|
||||
|
||||
lotsContainerElement.querySelector("tbody").append(rowElement);
|
||||
}
|
||||
};
|
||||
|
||||
const renderRelatedLotsAndOccupancies = () => {
|
||||
renderRelatedOccupancies();
|
||||
renderRelatedLots();
|
||||
};
|
||||
|
||||
renderRelatedLotsAndOccupancies();
|
||||
}
|
||||
|
||||
/*
|
||||
* Comments
|
||||
*/
|
||||
|
||||
/*
|
||||
* Milestones
|
||||
*/
|
||||
})();
|
||||
|
|
@ -0,0 +1 @@
|
|||
export {};
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
(() => {
|
||||
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
|
||||
const reopenWorkOrderButtonElement = document.querySelector("#button--reopenWorkOrder");
|
||||
if (reopenWorkOrderButtonElement) {
|
||||
reopenWorkOrderButtonElement.addEventListener("click", () => {
|
||||
const workOrderId = reopenWorkOrderButtonElement.dataset.workOrderId;
|
||||
const doReopen = () => {
|
||||
cityssm.postJSON(urlPrefix + "/workOrders/doReopenWorkOrder", {
|
||||
workOrderId
|
||||
}, (responseJSON) => {
|
||||
if (responseJSON.success) {
|
||||
window.location.href =
|
||||
urlPrefix +
|
||||
"/workOrders/" +
|
||||
workOrderId +
|
||||
"/edit/?t=" +
|
||||
Date.now();
|
||||
}
|
||||
else {
|
||||
bulmaJS.alert({
|
||||
title: "Error Reopening Work Order",
|
||||
message: responseJSON.errorMessage,
|
||||
contextualColorName: "danger"
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
bulmaJS.confirm({
|
||||
title: "Reopen Work Order",
|
||||
message: "Are you sure you want to remove the close date from this work order and reopen it?",
|
||||
contextualColorName: "warning",
|
||||
okButton: {
|
||||
text: "Yes, Reopen Work Order",
|
||||
callbackFunction: doReopen
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/* eslint-disable unicorn/prefer-module */
|
||||
|
||||
import type { cityssmGlobal } from "@cityssm/bulma-webapp-js/src/types";
|
||||
import type { BulmaJS } from "@cityssm/bulma-js/types";
|
||||
|
||||
declare const cityssm: cityssmGlobal;
|
||||
declare const bulmaJS: BulmaJS;
|
||||
|
||||
(() => {
|
||||
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
|
||||
|
||||
const reopenWorkOrderButtonElement = document.querySelector(
|
||||
"#button--reopenWorkOrder"
|
||||
) as HTMLButtonElement;
|
||||
|
||||
if (reopenWorkOrderButtonElement) {
|
||||
reopenWorkOrderButtonElement.addEventListener("click", () => {
|
||||
const workOrderId =
|
||||
reopenWorkOrderButtonElement.dataset.workOrderId;
|
||||
|
||||
const doReopen = () => {
|
||||
cityssm.postJSON(
|
||||
urlPrefix + "/workOrders/doReopenWorkOrder",
|
||||
{
|
||||
workOrderId
|
||||
},
|
||||
(responseJSON: {
|
||||
success: boolean;
|
||||
errorMessage?: string;
|
||||
}) => {
|
||||
if (responseJSON.success) {
|
||||
window.location.href =
|
||||
urlPrefix +
|
||||
"/workOrders/" +
|
||||
workOrderId +
|
||||
"/edit/?t=" +
|
||||
Date.now();
|
||||
} else {
|
||||
bulmaJS.alert({
|
||||
title: "Error Reopening Work Order",
|
||||
message: responseJSON.errorMessage,
|
||||
contextualColorName: "danger"
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
bulmaJS.confirm({
|
||||
title: "Reopen Work Order",
|
||||
message:
|
||||
"Are you sure you want to remove the close date from this work order and reopen it?",
|
||||
contextualColorName: "warning",
|
||||
okButton: {
|
||||
text: "Yes, Reopen Work Order",
|
||||
callbackFunction: doReopen
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1 @@
|
|||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,r=document.querySelector("#button--reopenWorkOrder");r&&r.addEventListener("click",()=>{const o=r.dataset.workOrderId;bulmaJS.confirm({title:"Reopen Work Order",message:"Are you sure you want to remove the close date from this work order and reopen it?",contextualColorName:"warning",okButton:{text:"Yes, Reopen Work Order",callbackFunction:()=>{cityssm.postJSON(e+"/workOrders/doReopenWorkOrder",{workOrderId:o},r=>{r.success?window.location.href=e+"/workOrders/"+o+"/edit/?t="+Date.now():bulmaJS.alert({title:"Error Reopening Work Order",message:r.errorMessage,contextualColorName:"danger"})})}}})})})();
|
||||
|
|
@ -3,10 +3,18 @@ import * as permissionHandlers from "../handlers/permissions.js";
|
|||
import handler_search from "../handlers/workOrders-get/search.js";
|
||||
import handler_doSearchWorkOrders from "../handlers/workOrders-post/doSearchWorkOrders.js";
|
||||
import handler_view from "../handlers/workOrders-get/view.js";
|
||||
import handler_doReopenWorkOrder from "../handlers/workOrders-post/doReopenWorkOrder.js";
|
||||
import handler_edit from "../handlers/workOrders-get/edit.js";
|
||||
import handler_doUpdateWorkOrder from "../handlers/workOrders-post/doUpdateWorkOrder.js";
|
||||
import handler_doDeleteWorkOrderLotOccupancy from "../handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.js";
|
||||
import handler_doDeleteWorkOrderLot from "../handlers/workOrders-post/doDeleteWorkOrderLot.js";
|
||||
export const router = Router();
|
||||
router.get("/", handler_search);
|
||||
router.post("/doSearchWorkOrders", handler_doSearchWorkOrders);
|
||||
router.get("/:workOrderId", handler_view);
|
||||
router.post("/doReopenWorkOrder", permissionHandlers.updatePostHandler, handler_doReopenWorkOrder);
|
||||
router.get("/:workOrderId/edit", permissionHandlers.updateGetHandler, handler_edit);
|
||||
router.post("/doUpdateWorkOrder", permissionHandlers.updatePostHandler, handler_doUpdateWorkOrder);
|
||||
router.post("/doDeleteWorkOrderLotOccupancy", permissionHandlers.updatePostHandler, handler_doDeleteWorkOrderLotOccupancy);
|
||||
router.post("/doDeleteWorkOrderLot", permissionHandlers.updatePostHandler, handler_doDeleteWorkOrderLot);
|
||||
export default router;
|
||||
|
|
|
|||
|
|
@ -6,8 +6,12 @@ import handler_search from "../handlers/workOrders-get/search.js";
|
|||
import handler_doSearchWorkOrders from "../handlers/workOrders-post/doSearchWorkOrders.js";
|
||||
|
||||
import handler_view from "../handlers/workOrders-get/view.js";
|
||||
import handler_doReopenWorkOrder from "../handlers/workOrders-post/doReopenWorkOrder.js";
|
||||
|
||||
import handler_edit from "../handlers/workOrders-get/edit.js";
|
||||
import handler_doUpdateWorkOrder from "../handlers/workOrders-post/doUpdateWorkOrder.js";
|
||||
import handler_doDeleteWorkOrderLotOccupancy from "../handlers/workOrders-post/doDeleteWorkOrderLotOccupancy.js";
|
||||
import handler_doDeleteWorkOrderLot from "../handlers/workOrders-post/doDeleteWorkOrderLot.js";
|
||||
|
||||
export const router = Router();
|
||||
|
||||
|
|
@ -17,8 +21,34 @@ router.post("/doSearchWorkOrders", handler_doSearchWorkOrders);
|
|||
|
||||
router.get("/:workOrderId", handler_view);
|
||||
|
||||
router.get("/:workOrderId/edit",
|
||||
router.post(
|
||||
"/doReopenWorkOrder",
|
||||
permissionHandlers.updatePostHandler,
|
||||
handler_doReopenWorkOrder
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/:workOrderId/edit",
|
||||
permissionHandlers.updateGetHandler,
|
||||
handler_edit);
|
||||
handler_edit
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/doUpdateWorkOrder",
|
||||
permissionHandlers.updatePostHandler,
|
||||
handler_doUpdateWorkOrder
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/doDeleteWorkOrderLotOccupancy",
|
||||
permissionHandlers.updatePostHandler,
|
||||
handler_doDeleteWorkOrderLotOccupancy
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/doDeleteWorkOrderLot",
|
||||
permissionHandlers.updatePostHandler,
|
||||
handler_doDeleteWorkOrderLot
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ export interface Lot extends Record {
|
|||
lotId?: number;
|
||||
lotName?: string;
|
||||
lotTypeId?: number;
|
||||
lotType?: LotType | string;
|
||||
lotType?: string;
|
||||
mapId?: number;
|
||||
mapName?: string;
|
||||
map?: Map;
|
||||
|
|
@ -61,7 +61,7 @@ export interface Lot extends Record {
|
|||
lotLatitude?: number;
|
||||
lotLongitude?: number;
|
||||
lotStatusId?: number;
|
||||
lotStatus?: LotStatus | string;
|
||||
lotStatus?: string;
|
||||
lotOccupancyCount?: number;
|
||||
lotOccupancies?: LotOccupancy[];
|
||||
lotComments?: LotComment[];
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ export interface Lot extends Record {
|
|||
lotName?: string;
|
||||
|
||||
lotTypeId?: number;
|
||||
lotType?: LotType | string;
|
||||
lotType?: string;
|
||||
|
||||
mapId?: number;
|
||||
mapName?: string;
|
||||
|
|
@ -82,7 +82,7 @@ export interface Lot extends Record {
|
|||
lotLongitude?: number;
|
||||
|
||||
lotStatusId?: number;
|
||||
lotStatus?: LotStatus | string;
|
||||
lotStatus?: string;
|
||||
|
||||
lotOccupancyCount?: number;
|
||||
lotOccupancies?: LotOccupancy[];
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@
|
|||
<span>Work Orders</span>
|
||||
</a>
|
||||
</li>
|
||||
<% if (isCreate) { %>
|
||||
<li class="is-active">
|
||||
<a href="#" aria-current="page">
|
||||
Create a New Work Order
|
||||
</a>
|
||||
</li>
|
||||
<% } else { %>
|
||||
<li>
|
||||
<a href="<%= urlPrefix %>/workOrders/<%= workOrder.workOrderId %>">
|
||||
Work Order #<%= workOrder.workOrderNumber || "(No Number)" %>
|
||||
|
|
@ -19,9 +26,164 @@
|
|||
Update Work Order
|
||||
</a>
|
||||
</li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<h1 class="title is-1">
|
||||
<% if (isCreate) { %>
|
||||
Create a New Work Order
|
||||
<% } else { %>
|
||||
Work Order #<%= workOrder.workOrderNumber || "(No Number)" %>
|
||||
<% } %>
|
||||
</h1>
|
||||
|
||||
<form id="form--workOrderEdit">
|
||||
<input id="workOrderEdit--workOrderId" name="workOrderId" type="hidden" value="<%= workOrder.workOrderId %>" />
|
||||
<div class="panel">
|
||||
<div class="panel-block is-block">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<label class="label" for="workOrderEdit--workOrderNumber">Work Order Number</label>
|
||||
<div class="control">
|
||||
<input class="input" id="workOrderEdit--workOrderNumber" name="workOrderNumber" type="text" value="<%= workOrder.workOrderNumber %>" maxlength="50" required />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<label class="label" for="workOrderEdit--workOrderTypeId">Work Order Type</label>
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select id="workOrderEdit--workOrderTypeId" name="workOrderTypeId" required>
|
||||
<% if (isCreate) { %>
|
||||
<option value="">(Select Type)</option>
|
||||
<% } %>
|
||||
<% for (const workOrderType of workOrderTypes) { %>
|
||||
<option value="<%= workOrderType.workOrderTypeId %>" <%= (workOrder.workOrderTypeId === workOrderType.workOrderTypeId ? " selected" : "") %>>
|
||||
<%= workOrderType.workOrderType %>
|
||||
</option>
|
||||
<% } %>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="workOrderEdit--workOrderDescription">Description</label>
|
||||
<div class="control">
|
||||
<textarea class="textarea" id="workOrderEdit--workOrderDescription" name="workOrderDescription"><%= workOrder.workOrderDescription %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<label class="label" for="workOrderEdit--workOrderOpenDateString">Open Date</label>
|
||||
<div class="control">
|
||||
<input class="input" id="workOrderEdit--workOrderOpenDateString" name="workOrderOpenDateString" type="date" value="<%= workOrder.workOrderOpenDateString %>" required />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
<label class="label" for="workOrderEdit--workOrderCloseDateString">Close Date</label>
|
||||
<div class="control">
|
||||
<input class="input" id="workOrderEdit--workOrderCloseDateString" name="workOrderCloseDateString" type="date" value="<%= workOrder.workOrderCloseDateString %>" disabled readonly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-block is-justify-content-flex-end">
|
||||
<button class="button is-success" type="submit">
|
||||
<span class="icon is-small"><i class="fas fa-save" aria-hidden="true"></i></span>
|
||||
<span>
|
||||
<%= (isCreate ? "Create" : "Update") %>
|
||||
Work Order
|
||||
</span>
|
||||
</button>
|
||||
<% if (!isCreate) { %>
|
||||
<div class="dropdown is-right ml-2">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button" type="button">
|
||||
<span>More Options</span>
|
||||
<span class="icon is-small"><i class="fas fa-caret-down" aria-hidden="true"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu">
|
||||
<div class="dropdown-content">
|
||||
<a class="dropdown-item" href="#">
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-trash has-text-danger" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span>Delete Work Order</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<% if (!isCreate) { %>
|
||||
<div class="panel">
|
||||
<div class="panel-heading">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<h2 class="title has-text-weight-bold is-5">Related <%= configFunctions.getProperty("aliases.lots") %></h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<div class="level-item">
|
||||
<button class="button is-small is-success" id="button--addWorkOrderLot" type="button">
|
||||
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
|
||||
<span>Add <%= configFunctions.getProperty("aliases.lots") %></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-block is-block">
|
||||
<%
|
||||
const tabToSelect = (workOrder.workOrderLotOccupancies.length > 0 || workOrder.workOrderLots.length === 0 ? "lotOccupancies" : "lots");
|
||||
%>
|
||||
<div class="tabs is-boxed">
|
||||
<ul>
|
||||
<li class="<%= (tabToSelect === "lotOccupancies" ? "is-active" : "") %>">
|
||||
<a href="#relatedTab--lotOccupancies">
|
||||
<span><%= configFunctions.getProperty("aliases.occupancies") %></span>
|
||||
<span class="ml-2 tag"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<%= (tabToSelect === "lots" ? "is-active" : "") %>">
|
||||
<a href="#relatedTab--lots">
|
||||
<span><%= configFunctions.getProperty("aliases.lots") %></span>
|
||||
<span class="ml-2 tag"></span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<div class="<%= (tabToSelect === "lotOccupancies" ? "" : "is-hidden") %>" id="relatedTab--lotOccupancies">
|
||||
</div>
|
||||
<div class="<%= (tabToSelect === "lots" ? "" : "is-hidden") %>" id="relatedTab--lots">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</form>
|
||||
|
||||
<%- include('_footerA'); -%>
|
||||
|
||||
<script>
|
||||
exports.workOrderComments = <%- JSON.stringify(workOrder.workOrderComments) %>;
|
||||
exports.workOrderLots = <%- JSON.stringify(workOrder.workOrderLots) %>;
|
||||
exports.workOrderLotOccupancies = <%- JSON.stringify(workOrder.workOrderLotOccupancies) %>;
|
||||
exports.workOrderMilestones = <%- JSON.stringify(workOrder.workOrderMilestones) %>;
|
||||
</script>
|
||||
<script src="<% urlPrefix %>/javascripts/workOrderEdit.min.js"></script>
|
||||
|
||||
<%- include('_footerB'); -%>
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
Work Order #<%= workOrder.workOrderNumber || "(No Number)" %>
|
||||
</h1>
|
||||
|
||||
<% if (user.userProperties.canUpdate) { %>
|
||||
<% if (user.userProperties.canUpdate && !workOrder.workOrderCloseDate) { %>
|
||||
<div class="fixed-container is-fixed-bottom-right mx-4 my-4 has-text-right is-hidden-print">
|
||||
<a class="button is-circle is-primary has-tooltip-left" data-tooltip="Update Work Order" href="<%= urlPrefix %>/workOrders/<%= workOrder.workOrderId %>/edit">
|
||||
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
|
||||
|
|
@ -65,6 +65,13 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% if (user.userProperties.canUpdate && workOrder.workOrderCloseDate) { %>
|
||||
<div class="panel-block is-justify-content-flex-end">
|
||||
<button class="button is-warning" id="button--reopenWorkOrder" data-work-order-id="<%= workOrder.workOrderId %>" type="button">
|
||||
Reopen Work Order
|
||||
</button>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
<div class="panel">
|
||||
|
|
@ -101,6 +108,7 @@
|
|||
</p>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<% const currentDate = dateTimeFunctions.dateToInteger(new Date()); %>
|
||||
<table class="table is-fullwidth is-striped is-hoverable">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
@ -207,6 +215,34 @@
|
|||
<div class="column is-4">
|
||||
<div class="panel">
|
||||
<h2 class="panel-heading">Milestones</h2>
|
||||
<% for (const milestone of workOrder.workOrderMilestones) { %>
|
||||
<div class="panel-block is-block">
|
||||
<div class="columns">
|
||||
<div class="column is-narrow">
|
||||
<% if (milestone.workOrderMilestoneCompletionDate) { %>
|
||||
<span class="icon is-small" data-tooltip="Completed <%= milestone.workOrderMilestoneCompletionDateString %>">
|
||||
<i class="fas fa-check" aria-label="Completed <%= milestone.workOrderMilestoneCompletionDateString %>"></i>
|
||||
</span>
|
||||
<% } else { %>
|
||||
<span class="icon is-small">
|
||||
<i class="far fa-square has-text-grey" aria-label="Incomplete"></i>
|
||||
</span>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="column">
|
||||
<% if (milestone.workOrderMilestoneTypeId) { %>
|
||||
<strong><%= milestone.workOrderMilestoneType %></strong><br />
|
||||
<% } %>
|
||||
<%= milestone.workOrderMilestoneDateString %>
|
||||
<% if (milestone.workOrderMilestoneTime !== 0) { %>
|
||||
<%= milestone.workOrderMilestoneTimeString %>
|
||||
<% } %>
|
||||
<br />
|
||||
<span class="is-size-7"><%= milestone.workOrderMilestoneDescription %></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
|
|
@ -214,4 +250,6 @@
|
|||
|
||||
<%- include('_footerA'); -%>
|
||||
|
||||
<script src="<%= urlPrefix %>/javascripts/workOrderView.min.js"></script>
|
||||
|
||||
<%- include('_footerB'); -%>
|
||||
Loading…
Reference in New Issue