show conflicting milestones when scheduling

closes #87
deepsource-autofix-76c6eb20
Dan Gowans 2024-06-25 13:42:51 -04:00
parent 5a4de85190
commit 20d3d89558
10 changed files with 527 additions and 250 deletions

View File

@ -1,9 +1,10 @@
import { type DateString } from '@cityssm/utils-datetime';
import type { PoolConnection } from 'better-sqlite-pool';
import type { WorkOrderMilestone } from '../types/recordTypes.js';
export interface WorkOrderMilestoneFilters {
workOrderId?: number | string;
workOrderMilestoneDateFilter?: 'upcomingMissed' | 'recent' | 'date' | 'blank' | 'notBlank';
workOrderMilestoneDateString?: string;
workOrderMilestoneDateString?: '' | DateString;
workOrderTypeIds?: string;
workOrderMilestoneTypeIds?: string;
}

View File

@ -42,11 +42,12 @@ function buildWhereClause(filters) {
break;
}
}
if ((filters.workOrderMilestoneDateString ?? '') !== '') {
if (filters.workOrderMilestoneDateString !== undefined && filters.workOrderMilestoneDateString !== '') {
sqlWhereClause += ' and m.workOrderMilestoneDate = ?';
sqlParameters.push(dateStringToInteger(filters.workOrderMilestoneDateString));
}
if ((filters.workOrderTypeIds ?? '') !== '' &&
if (filters.workOrderTypeIds !== undefined &&
filters.workOrderTypeIds !== '' &&
commaSeparatedNumbersRegex.test(filters.workOrderTypeIds)) {
sqlWhereClause += ` and w.workOrderTypeId in (${filters.workOrderTypeIds})`;
}

View File

@ -23,7 +23,7 @@ export interface WorkOrderMilestoneFilters {
| 'date'
| 'blank'
| 'notBlank'
workOrderMilestoneDateString?: string
workOrderMilestoneDateString?: '' | DateString
workOrderTypeIds?: string
workOrderMilestoneTypeIds?: string
}
@ -33,6 +33,7 @@ interface WorkOrderMilestoneOptions {
orderBy: 'completion' | 'date'
}
// eslint-disable-next-line security/detect-unsafe-regex
const commaSeparatedNumbersRegex = /^\d+(?:,\d+)*$/
function buildWhereClause(filters: WorkOrderMilestoneFilters): {
@ -98,16 +99,17 @@ function buildWhereClause(filters: WorkOrderMilestoneFilters): {
}
}
if ((filters.workOrderMilestoneDateString ?? '') !== '') {
if (filters.workOrderMilestoneDateString !== undefined && filters.workOrderMilestoneDateString !== '') {
sqlWhereClause += ' and m.workOrderMilestoneDate = ?'
sqlParameters.push(
dateStringToInteger(filters.workOrderMilestoneDateString as DateString)
dateStringToInteger(filters.workOrderMilestoneDateString)
)
}
if (
(filters.workOrderTypeIds ?? '') !== '' &&
commaSeparatedNumbersRegex.test(filters.workOrderTypeIds!)
filters.workOrderTypeIds !== undefined &&
filters.workOrderTypeIds !== '' &&
commaSeparatedNumbersRegex.test(filters.workOrderTypeIds)
) {
sqlWhereClause += ` and w.workOrderTypeId in (${filters.workOrderTypeIds})`
}
@ -115,7 +117,7 @@ function buildWhereClause(filters: WorkOrderMilestoneFilters): {
if (
filters.workOrderMilestoneTypeIds !== undefined &&
filters.workOrderMilestoneTypeIds !== '' &&
commaSeparatedNumbersRegex.test(filters.workOrderMilestoneTypeIds!)
commaSeparatedNumbersRegex.test(filters.workOrderMilestoneTypeIds)
) {
sqlWhereClause += ` and m.workOrderMilestoneTypeId in (${filters.workOrderMilestoneTypeIds})`
}

View File

@ -1,15 +1,20 @@
import type { Request, Response } from 'express'
import getWorkOrderMilestones from '../../database/getWorkOrderMilestones.js'
import getWorkOrderMilestones, {
type WorkOrderMilestoneFilters
} from '../../database/getWorkOrderMilestones.js'
export default async function handler(
request: Request,
response: Response
): Promise<void> {
const workOrderMilestones = await getWorkOrderMilestones(request.body, {
const workOrderMilestones = await getWorkOrderMilestones(
request.body as WorkOrderMilestoneFilters,
{
includeWorkOrders: true,
orderBy: 'date'
})
}
)
response.json({
workOrderMilestones

View File

@ -1,15 +1,15 @@
"use strict";
/* eslint-disable spaced-comment, @typescript-eslint/no-non-null-assertion, unicorn/prefer-module */
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable unicorn/prefer-module */
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
var _a, _b, _c;
var _a, _b, _c, _d;
const los = exports.los;
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((_a = workOrderFormElement
.querySelector('#workOrderEdit--workOrderOpenDateString')) === null || _a === void 0 ? void 0 : _a.closest('.field'));
los.initializeUnlockFieldButtons(workOrderFormElement);
function setUnsavedChanges() {
var _a;
@ -59,7 +59,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
* Work Order Options
*/
function doClose() {
cityssm.postJSON(los.urlPrefix + '/workOrders/doCloseWorkOrder', {
cityssm.postJSON(`${los.urlPrefix}/workOrders/doCloseWorkOrder`, {
workOrderId
}, (rawResponseJSON) => {
var _a;
@ -78,14 +78,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
});
}
function doDelete() {
cityssm.postJSON(los.urlPrefix + '/workOrders/doDeleteWorkOrder', {
cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrder`, {
workOrderId
}, (rawResponseJSON) => {
var _a;
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
clearUnsavedChanges();
window.location.href = los.urlPrefix + '/workOrders';
window.location.href = `${los.urlPrefix}/workOrders`;
}
else {
bulmaJS.alert({
@ -97,8 +97,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
});
}
let workOrderMilestones;
(_a = document
.querySelector('#button--closeWorkOrder')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => {
(_b = document
.querySelector('#button--closeWorkOrder')) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => {
const hasOpenMilestones = workOrderMilestones.some((milestone) => {
return !milestone.workOrderMilestoneCompletionDate;
});
@ -137,8 +137,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
});
}
});
(_b = document
.querySelector('#button--deleteWorkOrder')) === null || _b === void 0 ? void 0 : _b.addEventListener('click', (clickEvent) => {
(_c = document
.querySelector('#button--deleteWorkOrder')) === null || _c === void 0 ? void 0 : _c.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault();
bulmaJS.confirm({
title: 'Delete Work Order',
@ -914,6 +914,56 @@ Object.defineProperty(exports, "__esModule", { value: true });
/*
* Milestones
*/
function clearPanelBlockElements(panelElement) {
for (const panelBlockElement of panelElement.querySelectorAll('.panel-block')) {
panelBlockElement.remove();
}
}
function refreshConflictingMilestones(workOrderMilestoneDateString, targetPanelElement) {
// Clear panel-block elements
clearPanelBlockElements(targetPanelElement);
// eslint-disable-next-line no-unsanitized/method
targetPanelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block">
${los.getLoadingParagraphHTML('Loading conflicting milestones...')}
</div>`);
cityssm.postJSON(`${los.urlPrefix}/workOrders/doGetWorkOrderMilestones`, {
workOrderMilestoneDateFilter: 'date',
workOrderMilestoneDateString
}, (rawResponseJSON) => {
var _a, _b, _c, _d;
const responseJSON = rawResponseJSON;
const workOrderMilestones = responseJSON.workOrderMilestones.filter((possibleMilestone) => {
return possibleMilestone.workOrderId.toString() !== workOrderId;
});
clearPanelBlockElements(targetPanelElement);
for (const milestone of workOrderMilestones) {
targetPanelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block">
<div class="columns">
<div class="column is-5">
${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : (_a = milestone.workOrderMilestoneTimePeriodString) !== null && _a !== void 0 ? _a : '')}<br />
<strong>${cityssm.escapeHTML((_b = milestone.workOrderMilestoneType) !== null && _b !== void 0 ? _b : '')}</strong>
</div>
<div class="column">
${cityssm.escapeHTML((_c = milestone.workOrderNumber) !== null && _c !== void 0 ? _c : '')}<br />
<span class="is-size-7">
${cityssm.escapeHTML((_d = milestone.workOrderDescription) !== null && _d !== void 0 ? _d : '')}
</span>
</div>
</div>
</div>`);
}
if (workOrderMilestones.length === 0) {
targetPanelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block">
<div class="message is-info">
<p class="message-body">
There are no milestones on other work orders scheduled for
${cityssm.escapeHTML(workOrderMilestoneDateString)}.
</p>
</div>
</div>`);
}
});
}
function processMilestoneResponse(rawResponseJSON) {
var _a;
const responseJSON = rawResponseJSON;
@ -1002,9 +1052,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
return currentMilestone.workOrderMilestoneId === workOrderMilestoneId;
});
let editCloseModalFunction;
let workOrderMilestoneDateStringElement;
function doEdit(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(los.urlPrefix + '/workOrders/doUpdateWorkOrderMilestone', submitEvent.currentTarget, (rawResponseJSON) => {
cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateWorkOrderMilestone`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
processMilestoneResponse(responseJSON);
if (responseJSON.success) {
@ -1014,9 +1065,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
}
cityssm.openHtmlModal('workOrder-editMilestone', {
onshow(modalElement) {
var _a, _b, _c, _d, _e;
;
modalElement.querySelector('#milestoneEdit--workOrderId').value = workOrderId;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneId').value = workOrderMilestone.workOrderMilestoneId.toString();
modalElement.querySelector('#milestoneEdit--workOrderMilestoneId').value = (_b = (_a = workOrderMilestone.workOrderMilestoneId) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '';
const milestoneTypeElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneTypeId');
let milestoneTypeFound = false;
for (const milestoneType of exports.workOrderMilestoneTypes) {
@ -1040,21 +1092,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
optionElement.selected = true;
milestoneTypeElement.append(optionElement);
}
;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneDateString').value = workOrderMilestone.workOrderMilestoneDateString;
workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneDateString');
workOrderMilestoneDateStringElement.value = (_c = workOrderMilestone.workOrderMilestoneDateString) !== null && _c !== void 0 ? _c : '';
if (workOrderMilestone.workOrderMilestoneTime) {
;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneTimeString').value = workOrderMilestone.workOrderMilestoneTimeString;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneTimeString').value = (_d = workOrderMilestone.workOrderMilestoneTimeString) !== null && _d !== void 0 ? _d : '';
}
;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneDescription').value = workOrderMilestone.workOrderMilestoneDescription;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneDescription').value = (_e = workOrderMilestone.workOrderMilestoneDescription) !== null && _e !== void 0 ? _e : '';
},
onshown(modalElement, closeModalFunction) {
var _a;
editCloseModalFunction = closeModalFunction;
bulmaJS.toggleHtmlClipped();
los.initializeDatePickers(modalElement);
// los.initializeTimePickers(modalElement);
modalElement.querySelector('form').addEventListener('submit', doEdit);
(_a = modalElement.querySelector('form')) === null || _a === void 0 ? void 0 : _a.addEventListener('submit', doEdit);
const conflictingMilestonePanelElement = document.querySelector('#milestoneEdit--conflictingMilestonesPanel');
workOrderMilestoneDateStringElement.addEventListener('change', () => {
refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement);
});
refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement);
},
onremoved() {
bulmaJS.toggleHtmlClipped();
@ -1152,10 +1210,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.workOrderMilestones;
delete exports.workOrderMilestones;
renderMilestones();
(_c = document
.querySelector('#button--addMilestone')) === null || _c === void 0 ? void 0 : _c.addEventListener('click', () => {
let addModalElement;
(_d = document
.querySelector('#button--addMilestone')) === null || _d === void 0 ? void 0 : _d.addEventListener('click', () => {
let addFormElement;
let workOrderMilestoneDateStringElement;
let addCloseModalFunction;
function doAdd(submitEvent) {
if (submitEvent) {
@ -1163,7 +1221,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
}
const currentDateString = cityssm.dateToString(new Date());
function _doAdd() {
cityssm.postJSON(los.urlPrefix + '/workOrders/doAddWorkOrderMilestone', addFormElement, (rawResponseJSON) => {
cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderMilestone`, addFormElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
processMilestoneResponse(responseJSON);
if (responseJSON.success) {
@ -1171,7 +1229,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
}
});
}
const milestoneDateString = addModalElement.querySelector('#milestoneAdd--workOrderMilestoneDateString').value;
const milestoneDateString = workOrderMilestoneDateStringElement.value;
if (milestoneDateString !== '' &&
milestoneDateString < currentDateString) {
bulmaJS.confirm({
@ -1200,11 +1258,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
optionElement.textContent = milestoneType.workOrderMilestoneType;
milestoneTypeElement.append(optionElement);
}
;
modalElement.querySelector('#milestoneAdd--workOrderMilestoneDateString').valueAsDate = new Date();
workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneAdd--workOrderMilestoneDateString');
workOrderMilestoneDateStringElement.valueAsDate = new Date();
},
onshown(modalElement, closeModalFunction) {
addModalElement = modalElement;
addCloseModalFunction = closeModalFunction;
los.initializeDatePickers(modalElement);
// los.initializeTimePickers(modalElement);
@ -1212,6 +1269,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
modalElement.querySelector('#milestoneAdd--workOrderMilestoneTypeId').focus();
addFormElement = modalElement.querySelector('form');
addFormElement.addEventListener('submit', doAdd);
const conflictingMilestonePanelElement = document.querySelector('#milestoneAdd--conflictingMilestonesPanel');
workOrderMilestoneDateStringElement.addEventListener('change', () => {
refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement);
});
refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement);
},
onremoved() {
bulmaJS.toggleHtmlClipped();

View File

@ -1,15 +1,15 @@
"use strict";
/* eslint-disable spaced-comment, @typescript-eslint/no-non-null-assertion, unicorn/prefer-module */
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* eslint-disable unicorn/prefer-module */
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
var _a, _b, _c;
var _a, _b, _c, _d;
const los = exports.los;
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((_a = workOrderFormElement
.querySelector('#workOrderEdit--workOrderOpenDateString')) === null || _a === void 0 ? void 0 : _a.closest('.field'));
los.initializeUnlockFieldButtons(workOrderFormElement);
function setUnsavedChanges() {
var _a;
@ -59,7 +59,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
* Work Order Options
*/
function doClose() {
cityssm.postJSON(los.urlPrefix + '/workOrders/doCloseWorkOrder', {
cityssm.postJSON(`${los.urlPrefix}/workOrders/doCloseWorkOrder`, {
workOrderId
}, (rawResponseJSON) => {
var _a;
@ -78,14 +78,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
});
}
function doDelete() {
cityssm.postJSON(los.urlPrefix + '/workOrders/doDeleteWorkOrder', {
cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrder`, {
workOrderId
}, (rawResponseJSON) => {
var _a;
const responseJSON = rawResponseJSON;
if (responseJSON.success) {
clearUnsavedChanges();
window.location.href = los.urlPrefix + '/workOrders';
window.location.href = `${los.urlPrefix}/workOrders`;
}
else {
bulmaJS.alert({
@ -97,8 +97,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
});
}
let workOrderMilestones;
(_a = document
.querySelector('#button--closeWorkOrder')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => {
(_b = document
.querySelector('#button--closeWorkOrder')) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => {
const hasOpenMilestones = workOrderMilestones.some((milestone) => {
return !milestone.workOrderMilestoneCompletionDate;
});
@ -137,8 +137,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
});
}
});
(_b = document
.querySelector('#button--deleteWorkOrder')) === null || _b === void 0 ? void 0 : _b.addEventListener('click', (clickEvent) => {
(_c = document
.querySelector('#button--deleteWorkOrder')) === null || _c === void 0 ? void 0 : _c.addEventListener('click', (clickEvent) => {
clickEvent.preventDefault();
bulmaJS.confirm({
title: 'Delete Work Order',
@ -163,6 +163,56 @@ Object.defineProperty(exports, "__esModule", { value: true });
/*
* Milestones
*/
function clearPanelBlockElements(panelElement) {
for (const panelBlockElement of panelElement.querySelectorAll('.panel-block')) {
panelBlockElement.remove();
}
}
function refreshConflictingMilestones(workOrderMilestoneDateString, targetPanelElement) {
// Clear panel-block elements
clearPanelBlockElements(targetPanelElement);
// eslint-disable-next-line no-unsanitized/method
targetPanelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block">
${los.getLoadingParagraphHTML('Loading conflicting milestones...')}
</div>`);
cityssm.postJSON(`${los.urlPrefix}/workOrders/doGetWorkOrderMilestones`, {
workOrderMilestoneDateFilter: 'date',
workOrderMilestoneDateString
}, (rawResponseJSON) => {
var _a, _b, _c, _d;
const responseJSON = rawResponseJSON;
const workOrderMilestones = responseJSON.workOrderMilestones.filter((possibleMilestone) => {
return possibleMilestone.workOrderId.toString() !== workOrderId;
});
clearPanelBlockElements(targetPanelElement);
for (const milestone of workOrderMilestones) {
targetPanelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block">
<div class="columns">
<div class="column is-5">
${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : (_a = milestone.workOrderMilestoneTimePeriodString) !== null && _a !== void 0 ? _a : '')}<br />
<strong>${cityssm.escapeHTML((_b = milestone.workOrderMilestoneType) !== null && _b !== void 0 ? _b : '')}</strong>
</div>
<div class="column">
${cityssm.escapeHTML((_c = milestone.workOrderNumber) !== null && _c !== void 0 ? _c : '')}<br />
<span class="is-size-7">
${cityssm.escapeHTML((_d = milestone.workOrderDescription) !== null && _d !== void 0 ? _d : '')}
</span>
</div>
</div>
</div>`);
}
if (workOrderMilestones.length === 0) {
targetPanelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block">
<div class="message is-info">
<p class="message-body">
There are no milestones on other work orders scheduled for
${cityssm.escapeHTML(workOrderMilestoneDateString)}.
</p>
</div>
</div>`);
}
});
}
function processMilestoneResponse(rawResponseJSON) {
var _a;
const responseJSON = rawResponseJSON;
@ -251,9 +301,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
return currentMilestone.workOrderMilestoneId === workOrderMilestoneId;
});
let editCloseModalFunction;
let workOrderMilestoneDateStringElement;
function doEdit(submitEvent) {
submitEvent.preventDefault();
cityssm.postJSON(los.urlPrefix + '/workOrders/doUpdateWorkOrderMilestone', submitEvent.currentTarget, (rawResponseJSON) => {
cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateWorkOrderMilestone`, submitEvent.currentTarget, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
processMilestoneResponse(responseJSON);
if (responseJSON.success) {
@ -263,9 +314,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
}
cityssm.openHtmlModal('workOrder-editMilestone', {
onshow(modalElement) {
var _a, _b, _c, _d, _e;
;
modalElement.querySelector('#milestoneEdit--workOrderId').value = workOrderId;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneId').value = workOrderMilestone.workOrderMilestoneId.toString();
modalElement.querySelector('#milestoneEdit--workOrderMilestoneId').value = (_b = (_a = workOrderMilestone.workOrderMilestoneId) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '';
const milestoneTypeElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneTypeId');
let milestoneTypeFound = false;
for (const milestoneType of exports.workOrderMilestoneTypes) {
@ -289,21 +341,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
optionElement.selected = true;
milestoneTypeElement.append(optionElement);
}
;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneDateString').value = workOrderMilestone.workOrderMilestoneDateString;
workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneDateString');
workOrderMilestoneDateStringElement.value = (_c = workOrderMilestone.workOrderMilestoneDateString) !== null && _c !== void 0 ? _c : '';
if (workOrderMilestone.workOrderMilestoneTime) {
;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneTimeString').value = workOrderMilestone.workOrderMilestoneTimeString;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneTimeString').value = (_d = workOrderMilestone.workOrderMilestoneTimeString) !== null && _d !== void 0 ? _d : '';
}
;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneDescription').value = workOrderMilestone.workOrderMilestoneDescription;
modalElement.querySelector('#milestoneEdit--workOrderMilestoneDescription').value = (_e = workOrderMilestone.workOrderMilestoneDescription) !== null && _e !== void 0 ? _e : '';
},
onshown(modalElement, closeModalFunction) {
var _a;
editCloseModalFunction = closeModalFunction;
bulmaJS.toggleHtmlClipped();
los.initializeDatePickers(modalElement);
// los.initializeTimePickers(modalElement);
modalElement.querySelector('form').addEventListener('submit', doEdit);
(_a = modalElement.querySelector('form')) === null || _a === void 0 ? void 0 : _a.addEventListener('submit', doEdit);
const conflictingMilestonePanelElement = document.querySelector('#milestoneEdit--conflictingMilestonesPanel');
workOrderMilestoneDateStringElement.addEventListener('change', () => {
refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement);
});
refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement);
},
onremoved() {
bulmaJS.toggleHtmlClipped();
@ -401,10 +459,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.workOrderMilestones;
delete exports.workOrderMilestones;
renderMilestones();
(_c = document
.querySelector('#button--addMilestone')) === null || _c === void 0 ? void 0 : _c.addEventListener('click', () => {
let addModalElement;
(_d = document
.querySelector('#button--addMilestone')) === null || _d === void 0 ? void 0 : _d.addEventListener('click', () => {
let addFormElement;
let workOrderMilestoneDateStringElement;
let addCloseModalFunction;
function doAdd(submitEvent) {
if (submitEvent) {
@ -412,7 +470,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
}
const currentDateString = cityssm.dateToString(new Date());
function _doAdd() {
cityssm.postJSON(los.urlPrefix + '/workOrders/doAddWorkOrderMilestone', addFormElement, (rawResponseJSON) => {
cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderMilestone`, addFormElement, (rawResponseJSON) => {
const responseJSON = rawResponseJSON;
processMilestoneResponse(responseJSON);
if (responseJSON.success) {
@ -420,7 +478,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
}
});
}
const milestoneDateString = addModalElement.querySelector('#milestoneAdd--workOrderMilestoneDateString').value;
const milestoneDateString = workOrderMilestoneDateStringElement.value;
if (milestoneDateString !== '' &&
milestoneDateString < currentDateString) {
bulmaJS.confirm({
@ -449,11 +507,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
optionElement.textContent = milestoneType.workOrderMilestoneType;
milestoneTypeElement.append(optionElement);
}
;
modalElement.querySelector('#milestoneAdd--workOrderMilestoneDateString').valueAsDate = new Date();
workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneAdd--workOrderMilestoneDateString');
workOrderMilestoneDateStringElement.valueAsDate = new Date();
},
onshown(modalElement, closeModalFunction) {
addModalElement = modalElement;
addCloseModalFunction = closeModalFunction;
los.initializeDatePickers(modalElement);
// los.initializeTimePickers(modalElement);
@ -461,6 +518,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
modalElement.querySelector('#milestoneAdd--workOrderMilestoneTypeId').focus();
addFormElement = modalElement.querySelector('form');
addFormElement.addEventListener('submit', doAdd);
const conflictingMilestonePanelElement = document.querySelector('#milestoneAdd--conflictingMilestonesPanel');
workOrderMilestoneDateStringElement.addEventListener('change', () => {
refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement);
});
refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement);
},
onremoved() {
bulmaJS.toggleHtmlClipped();

View File

@ -1,13 +1,16 @@
/* eslint-disable spaced-comment, @typescript-eslint/no-non-null-assertion, unicorn/prefer-module */
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
/* 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 { BulmaJS } from '@cityssm/bulma-js/types.js'
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js'
import type * as globalTypes from '../../types/globalTypes'
import type * as recordTypes from '../../types/recordTypes'
import type * as globalTypes from '../../types/globalTypes.js'
import type * as recordTypes from '../../types/recordTypes.js'
declare const cityssm: cityssmGlobal
declare const bulmaJS: BulmaJS
declare const exports: Record<string, unknown>
;(() => {
const los = exports.los as globalTypes.LOS
@ -23,8 +26,8 @@ declare const bulmaJS: BulmaJS
los.initializeDatePickers(
workOrderFormElement
.querySelector('#workOrderEdit--workOrderOpenDateString')!
.closest('.field') as HTMLElement
.querySelector('#workOrderEdit--workOrderOpenDateString')
?.closest('.field') as HTMLElement
)
los.initializeUnlockFieldButtons(workOrderFormElement)
@ -96,7 +99,7 @@ declare const bulmaJS: BulmaJS
function doClose(): void {
cityssm.postJSON(
los.urlPrefix + '/workOrders/doCloseWorkOrder',
`${los.urlPrefix}/workOrders/doCloseWorkOrder`,
{
workOrderId
},
@ -122,7 +125,7 @@ declare const bulmaJS: BulmaJS
function doDelete(): void {
cityssm.postJSON(
los.urlPrefix + '/workOrders/doDeleteWorkOrder',
`${los.urlPrefix}/workOrders/doDeleteWorkOrder`,
{
workOrderId
},
@ -134,7 +137,7 @@ declare const bulmaJS: BulmaJS
if (responseJSON.success) {
clearUnsavedChanges()
window.location.href = los.urlPrefix + '/workOrders'
window.location.href = `${los.urlPrefix}/workOrders`
} else {
bulmaJS.alert({
title: 'Error Deleting Work Order',
@ -225,15 +228,94 @@ declare const bulmaJS: BulmaJS
* Milestones
*/
function clearPanelBlockElements(panelElement: HTMLElement): void {
for (const panelBlockElement of panelElement.querySelectorAll(
'.panel-block'
)) {
panelBlockElement.remove()
}
}
function refreshConflictingMilestones(
workOrderMilestoneDateString: string,
targetPanelElement: HTMLElement
): void {
// Clear panel-block elements
clearPanelBlockElements(targetPanelElement)
// eslint-disable-next-line no-unsanitized/method
targetPanelElement.insertAdjacentHTML(
'beforeend',
`<div class="panel-block is-block">
${los.getLoadingParagraphHTML('Loading conflicting milestones...')}
</div>`
)
cityssm.postJSON(
`${los.urlPrefix}/workOrders/doGetWorkOrderMilestones`,
{
workOrderMilestoneDateFilter: 'date',
workOrderMilestoneDateString
},
(rawResponseJSON) => {
const responseJSON = rawResponseJSON as {
workOrderMilestones: recordTypes.WorkOrderMilestone[]
}
const workOrderMilestones = responseJSON.workOrderMilestones.filter(
(possibleMilestone) => {
return possibleMilestone.workOrderId.toString() !== workOrderId
}
)
clearPanelBlockElements(targetPanelElement)
for (const milestone of workOrderMilestones) {
targetPanelElement.insertAdjacentHTML(
'beforeend',
`<div class="panel-block is-block">
<div class="columns">
<div class="column is-5">
${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : milestone.workOrderMilestoneTimePeriodString ?? '')}<br />
<strong>${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}</strong>
</div>
<div class="column">
${cityssm.escapeHTML(milestone.workOrderNumber ?? '')}<br />
<span class="is-size-7">
${cityssm.escapeHTML(milestone.workOrderDescription ?? '')}
</span>
</div>
</div>
</div>`
)
}
if (workOrderMilestones.length === 0) {
targetPanelElement.insertAdjacentHTML(
'beforeend',
`<div class="panel-block is-block">
<div class="message is-info">
<p class="message-body">
There are no milestones on other work orders scheduled for
${cityssm.escapeHTML(workOrderMilestoneDateString)}.
</p>
</div>
</div>`
)
}
}
)
}
function processMilestoneResponse(rawResponseJSON: unknown): void {
const responseJSON = rawResponseJSON as {
success: boolean
errorMessage?: string
workOrderMilestones?: recordTypes.WorkOrderMilestone[]
workOrderMilestones: recordTypes.WorkOrderMilestone[]
}
if (responseJSON.success) {
workOrderMilestones = responseJSON.workOrderMilestones!
workOrderMilestones = responseJSON.workOrderMilestones
renderMilestones()
} else {
bulmaJS.alert({
@ -370,12 +452,13 @@ declare const bulmaJS: BulmaJS
})!
let editCloseModalFunction: () => void
let workOrderMilestoneDateStringElement: HTMLInputElement
function doEdit(submitEvent: SubmitEvent): void {
submitEvent.preventDefault()
cityssm.postJSON(
los.urlPrefix + '/workOrders/doUpdateWorkOrderMilestone',
`${los.urlPrefix}/workOrders/doUpdateWorkOrderMilestone`,
submitEvent.currentTarget,
(rawResponseJSON) => {
const responseJSON = rawResponseJSON as {
@ -403,7 +486,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'
@ -441,25 +524,27 @@ declare const bulmaJS: BulmaJS
milestoneTypeElement.append(optionElement)
}
;(
workOrderMilestoneDateStringElement = (
modalElement.querySelector(
'#milestoneEdit--workOrderMilestoneDateString'
) as HTMLInputElement
).value = workOrderMilestone.workOrderMilestoneDateString!
)
workOrderMilestoneDateStringElement.value = workOrderMilestone.workOrderMilestoneDateString ?? ''
if (workOrderMilestone.workOrderMilestoneTime) {
;(
modalElement.querySelector(
'#milestoneEdit--workOrderMilestoneTimeString'
) as HTMLInputElement
).value = workOrderMilestone.workOrderMilestoneTimeString!
).value = workOrderMilestone.workOrderMilestoneTimeString ?? ''
}
;(
modalElement.querySelector(
'#milestoneEdit--workOrderMilestoneDescription'
) as HTMLTextAreaElement
).value = workOrderMilestone.workOrderMilestoneDescription!
).value = workOrderMilestone.workOrderMilestoneDescription ?? ''
},
onshown(modalElement, closeModalFunction) {
editCloseModalFunction = closeModalFunction
@ -468,7 +553,26 @@ declare const bulmaJS: BulmaJS
los.initializeDatePickers(modalElement)
// los.initializeTimePickers(modalElement);
modalElement.querySelector('form')!.addEventListener('submit', doEdit)
modalElement.querySelector('form')?.addEventListener('submit', doEdit)
const conflictingMilestonePanelElement = document.querySelector(
'#milestoneEdit--conflictingMilestonesPanel'
) as HTMLElement
workOrderMilestoneDateStringElement.addEventListener(
'change',
() => {
refreshConflictingMilestones(
workOrderMilestoneDateStringElement.value,
conflictingMilestonePanelElement
)
}
)
refreshConflictingMilestones(
workOrderMilestoneDateStringElement.value,
conflictingMilestonePanelElement
)
},
onremoved() {
bulmaJS.toggleHtmlClipped()
@ -588,8 +692,9 @@ declare const bulmaJS: BulmaJS
document
.querySelector('#button--addMilestone')
?.addEventListener('click', () => {
let addModalElement: HTMLElement
let addFormElement: HTMLFormElement
let workOrderMilestoneDateStringElement: HTMLInputElement
let addCloseModalFunction: () => void
function doAdd(submitEvent: SubmitEvent): void {
@ -601,7 +706,7 @@ declare const bulmaJS: BulmaJS
function _doAdd(): void {
cityssm.postJSON(
los.urlPrefix + '/workOrders/doAddWorkOrderMilestone',
`${los.urlPrefix}/workOrders/doAddWorkOrderMilestone`,
addFormElement,
(rawResponseJSON) => {
const responseJSON = rawResponseJSON as {
@ -619,11 +724,7 @@ declare const bulmaJS: BulmaJS
)
}
const milestoneDateString = (
addModalElement.querySelector(
'#milestoneAdd--workOrderMilestoneDateString'
) as HTMLInputElement
).value
const milestoneDateString = workOrderMilestoneDateStringElement.value
if (
milestoneDateString !== '' &&
@ -666,14 +767,14 @@ declare const bulmaJS: BulmaJS
milestoneTypeElement.append(optionElement)
}
;(
modalElement.querySelector(
workOrderMilestoneDateStringElement = modalElement.querySelector(
'#milestoneAdd--workOrderMilestoneDateString'
) as HTMLInputElement
).valueAsDate = new Date()
workOrderMilestoneDateStringElement.valueAsDate = new Date()
},
onshown(modalElement, closeModalFunction) {
addModalElement = modalElement
addCloseModalFunction = closeModalFunction
los.initializeDatePickers(modalElement)
@ -686,8 +787,29 @@ declare const bulmaJS: BulmaJS
) as HTMLSelectElement
).focus()
addFormElement = modalElement.querySelector('form')!
addFormElement = modalElement.querySelector(
'form'
) as HTMLFormElement
addFormElement.addEventListener('submit', doAdd)
const conflictingMilestonePanelElement = document.querySelector(
'#milestoneAdd--conflictingMilestonesPanel'
) as HTMLElement
workOrderMilestoneDateStringElement.addEventListener(
'change',
() => {
refreshConflictingMilestones(
workOrderMilestoneDateStringElement.value,
conflictingMilestonePanelElement
)
}
)
refreshConflictingMilestones(
workOrderMilestoneDateStringElement.value,
conflictingMilestonePanelElement
)
},
onremoved() {
bulmaJS.toggleHtmlClipped()

View File

@ -1,6 +1,6 @@
<div class="modal" role="dialog">
<div class="modal-background"></div>
<div class="modal-card">
<div class="modal-card" style="width:1000px">
<header class="modal-card-head">
<h3 class="modal-card-title">Add Milestone</h3>
<button
@ -10,6 +10,8 @@
></button>
</header>
<section class="modal-card-body">
<div class="columns">
<div class="column">
<form id="form--milestoneAdd">
<input
id="milestoneAdd--workOrderId"
@ -88,6 +90,15 @@
</div>
</div>
</form>
</div>
<div class="column">
<div class="panel is-info" id="milestoneAdd--conflictingMilestonesPanel">
<h4 class="panel-heading">
Potentially Conflicting Milestones
</h4>
</div>
</div>
</div>
</section>
<footer class="modal-card-foot justify-right">
<button class="button is-success" type="submit" form="form--milestoneAdd">

View File

@ -1,6 +1,6 @@
<div class="modal" role="dialog">
<div class="modal-background"></div>
<div class="modal-card">
<div class="modal-card" style="width:1000px">
<header class="modal-card-head">
<h3 class="modal-card-title">Edit Milestone</h3>
<button
@ -10,6 +10,8 @@
></button>
</header>
<section class="modal-card-body">
<div class="columns">
<div class="column">
<form id="form--milestoneEdit">
<input
id="milestoneEdit--workOrderId"
@ -96,6 +98,15 @@
</div>
</div>
</form>
</div>
<div class="column">
<div class="panel is-info" id="milestoneEdit--conflictingMilestonesPanel">
<h4 class="panel-heading">
Potentially Conflicting Milestones
</h4>
</div>
</div>
</div>
</section>
<footer class="modal-card-foot justify-right">
<button

File diff suppressed because one or more lines are too long