development

deepsource-autofix-76c6eb20
Dan Gowans 2022-07-21 16:18:30 -04:00
parent 012362c07b
commit 8595c82307
47 changed files with 16381 additions and 4516 deletions

View File

@ -8,9 +8,7 @@ export const config = {
lot: "Burial Site", lot: "Burial Site",
lots: "Burial Sites", lots: "Burial Sites",
map: "Cemetery", map: "Cemetery",
maps: "Cemeteries", maps: "Cemeteries"
occupancy: "Order",
occupancies: "Orders"
} }
}; };
export default config; export default config;

View File

@ -10,9 +10,7 @@ export const config: Config = {
lot: "Burial Site", lot: "Burial Site",
lots: "Burial Sites", lots: "Burial Sites",
map: "Cemetery", map: "Cemetery",
maps: "Cemeteries", maps: "Cemeteries"
occupancy: "Order",
occupancies: "Orders"
} }
}; };

View File

@ -1,8 +1,14 @@
import * as configFunctions from "../../helpers/functions.config.js"; import * as configFunctions from "../../helpers/functions.config.js";
import { getLot } from "../../helpers/lotOccupancyDB/getLot.js";
const urlPrefix = configFunctions.getProperty("reverseProxy.urlPrefix"); const urlPrefix = configFunctions.getProperty("reverseProxy.urlPrefix");
export const handler = (_request, response) => { export const handler = (request, response) => {
const lot = getLot(request.params.lotId);
if (!lot) {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lots/?error=lotIdNotFound");
}
return response.render("lot-view", { return response.render("lot-view", {
headTitle: "Licence View" headTitle: lot.lotName,
lot
}); });
}; };
export default handler; export default handler;

View File

@ -2,16 +2,24 @@ import type { RequestHandler } from "express";
import * as configFunctions from "../../helpers/functions.config.js"; import * as configFunctions from "../../helpers/functions.config.js";
import { getLot } from "../../helpers/lotOccupancyDB/getLot.js";
const urlPrefix = configFunctions.getProperty("reverseProxy.urlPrefix"); const urlPrefix = configFunctions.getProperty("reverseProxy.urlPrefix");
export const handler: RequestHandler = (_request, response) => { export const handler: RequestHandler = (request, response) => {
const lot = getLot(request.params.lotId);
if (!lot) {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/lots/?error=lotIdNotFound");
}
//const licenceID = Number(request.params.licenceID);
return response.render("lot-view", { return response.render("lot-view", {
headTitle: "Licence View" headTitle: lot.lotName,
lot
}); });
}; };

View File

@ -19,6 +19,4 @@ export declare function getProperty(propertyName: "aliases.lot"): string;
export declare function getProperty(propertyName: "aliases.lots"): string; export declare function getProperty(propertyName: "aliases.lots"): string;
export declare function getProperty(propertyName: "aliases.map"): string; export declare function getProperty(propertyName: "aliases.map"): string;
export declare function getProperty(propertyName: "aliases.maps"): string; export declare function getProperty(propertyName: "aliases.maps"): string;
export declare function getProperty(propertyName: "aliases.occupancy"): string;
export declare function getProperty(propertyName: "aliases.occupancies"): string;
export declare const keepAliveMillis: number; export declare const keepAliveMillis: number;

View File

@ -19,8 +19,6 @@ configFallbackValues.set("aliases.lot", "Lot");
configFallbackValues.set("aliases.lots", "Lots"); configFallbackValues.set("aliases.lots", "Lots");
configFallbackValues.set("aliases.map", "Map"); configFallbackValues.set("aliases.map", "Map");
configFallbackValues.set("aliases.maps", "Maps"); configFallbackValues.set("aliases.maps", "Maps");
configFallbackValues.set("aliases.occupancy", "Occupancy");
configFallbackValues.set("aliases.occupancies", "Occupancies");
export function getProperty(propertyName) { export function getProperty(propertyName) {
const propertyNameSplit = propertyName.split("."); const propertyNameSplit = propertyName.split(".");
let currentObject = config; let currentObject = config;

View File

@ -33,8 +33,6 @@ configFallbackValues.set("aliases.lot", "Lot");
configFallbackValues.set("aliases.lots", "Lots"); configFallbackValues.set("aliases.lots", "Lots");
configFallbackValues.set("aliases.map", "Map"); configFallbackValues.set("aliases.map", "Map");
configFallbackValues.set("aliases.maps", "Maps"); configFallbackValues.set("aliases.maps", "Maps");
configFallbackValues.set("aliases.occupancy", "Occupancy");
configFallbackValues.set("aliases.occupancies", "Occupancies");
/* /*
@ -66,8 +64,6 @@ export function getProperty(propertyName: "aliases.lot"): string;
export function getProperty(propertyName: "aliases.lots"): string; export function getProperty(propertyName: "aliases.lots"): string;
export function getProperty(propertyName: "aliases.map"): string; export function getProperty(propertyName: "aliases.map"): string;
export function getProperty(propertyName: "aliases.maps"): string; export function getProperty(propertyName: "aliases.maps"): string;
export function getProperty(propertyName: "aliases.occupancy"): string;
export function getProperty(propertyName: "aliases.occupancies"): string;
export function getProperty(propertyName: string): unknown { export function getProperty(propertyName: string): unknown {

View File

@ -0,0 +1,3 @@
import type * as recordTypes from "../../types/recordTypes";
export declare const getLot: (lotId: number | string) => recordTypes.Lot;
export default getLot;

View File

@ -0,0 +1,24 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
export const getLot = (lotId) => {
const database = sqlite(databasePath, {
readonly: true
});
const lot = database
.prepare("select l.lotId," +
" l.lotTypeId, t.lotType," +
" l.lotName," +
" l.lotStatusId, s.lotStatus," +
" l.mapId, m.mapName, m.mapSVG, l.mapKey," +
" l.lotLatitude, l.lotLongitude" +
" from Lots l" +
" left join LotTypes t on l.lotTypeId = t.lotTypeId" +
" left join LotStatuses s on l.lotStatusId = s.lotStatusId" +
" left join Maps m on l.mapId = m.mapId" +
" where l.recordDelete_timeMillis is null" +
" and l.lotId = ?")
.get(lotId);
database.close();
return lot;
};
export default getLot;

View File

@ -0,0 +1,36 @@
import sqlite from "better-sqlite3";
import {
lotOccupancyDB as databasePath
} from "../../data/databasePaths.js";
import type * as recordTypes from "../../types/recordTypes";
export const getLot = (lotId: number | string): recordTypes.Lot => {
const database = sqlite(databasePath, {
readonly: true
});
const lot: recordTypes.Lot = database
.prepare("select l.lotId," +
" l.lotTypeId, t.lotType," +
" l.lotName," +
" l.lotStatusId, s.lotStatus," +
" l.mapId, m.mapName, m.mapSVG, l.mapKey," +
" l.lotLatitude, l.lotLongitude" +
" from Lots l" +
" left join LotTypes t on l.lotTypeId = t.lotTypeId" +
" left join LotStatuses s on l.lotStatusId = s.lotStatusId" +
" left join Maps m on l.mapId = m.mapId" +
" where l.recordDelete_timeMillis is null" +
" and l.lotId = ?")
.get(lotId);
database.close();
return lot;
};
export default getLot;

View File

@ -1,5 +1,6 @@
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from "../../types/recordTypes";
interface GetLotsFilters { interface GetLotsFilters {
lotName?: string;
mapId?: number | string; mapId?: number | string;
lotTypeId?: number | string; lotTypeId?: number | string;
lotStatusId?: number | string; lotStatusId?: number | string;

View File

@ -1,3 +1,4 @@
import { dateToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import sqlite from "better-sqlite3"; import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
export const getLots = (filters, options) => { export const getLots = (filters, options) => {
@ -6,6 +7,13 @@ export const getLots = (filters, options) => {
}); });
let sqlWhereClause = ""; let sqlWhereClause = "";
const sqlParameters = []; const sqlParameters = [];
if (filters.lotName) {
const lotNamePieces = filters.lotName.toLowerCase().split(" ");
for (const lotNamePiece of lotNamePieces) {
sqlWhereClause += " and instr(lower(l.lotName), ?)";
sqlParameters.push(lotNamePiece);
}
}
if (filters.mapId) { if (filters.mapId) {
sqlWhereClause += " and l.mapId = ?"; sqlWhereClause += " and l.mapId = ?";
sqlParameters.push(filters.mapId); sqlParameters.push(filters.mapId);
@ -18,21 +26,31 @@ export const getLots = (filters, options) => {
sqlWhereClause += " and l.lotStatusId = ?"; sqlWhereClause += " and l.lotStatusId = ?";
sqlParameters.push(filters.lotStatusId); sqlParameters.push(filters.lotStatusId);
} }
const currentDate = dateToInteger(new Date());
const lots = database const lots = database
.prepare("select l.lotId, l.lotName," + .prepare("select l.lotId, l.lotName," +
" t.lotType," + " t.lotType," +
" m.mapName, l.mapKey," + " l.mapId, m.mapName, l.mapKey," +
" s.lotStatus" + " s.lotStatus," +
" ifnull(o.lotOccupancyCount, 0) as lotOccupancyCount" +
" from Lots l" + " from Lots l" +
" left join LotTypes t on l.lotTypeId = t.lotTypeId" + " left join LotTypes t on l.lotTypeId = t.lotTypeId" +
" left join LotStatuses s on l.lotStatusId = s.lotStatusId" + " left join LotStatuses s on l.lotStatusId = s.lotStatusId" +
" left join Maps m on l.mapId = m.mapId" + " left join Maps m on l.mapId = m.mapId" +
(" left join (" +
"select lotId, count(lotOccupancyId) as lotOccupancyCount" +
" from LotOccupancies" +
" where recordDelete_timeMillis is null" +
" and occupancyStartDate <= " + currentDate +
" and (occupancyEndDate is null or occupancyEndDate >= " + currentDate + ")" +
" group by lotId" +
") o on l.lotId = o.lotId") +
" where l.recordDelete_timeMillis is null" + " where l.recordDelete_timeMillis is null" +
sqlWhereClause + sqlWhereClause +
" order by l.lotName" + " order by l.lotName" +
(options (options ?
? " limit " + options.limit + " offset " + options.offset " limit " + options.limit + " offset " + options.offset :
: "")) ""))
.all(sqlParameters); .all(sqlParameters);
database.close(); database.close();
return lots; return lots;

View File

@ -1,3 +1,6 @@
import {
dateToInteger
} from "@cityssm/expressjs-server-js/dateTimeFns.js";
import sqlite from "better-sqlite3"; import sqlite from "better-sqlite3";
import { import {
lotOccupancyDB as databasePath lotOccupancyDB as databasePath
@ -7,6 +10,7 @@ import type * as recordTypes from "../../types/recordTypes";
interface GetLotsFilters { interface GetLotsFilters {
lotName?: string;
mapId ? : number | string; mapId ? : number | string;
lotTypeId ? : number | string; lotTypeId ? : number | string;
lotStatusId ? : number | string; lotStatusId ? : number | string;
@ -27,6 +31,14 @@ export const getLots = (filters ? : GetLotsFilters, options?: GetLotsOptions): r
let sqlWhereClause = ""; let sqlWhereClause = "";
const sqlParameters = []; const sqlParameters = [];
if (filters.lotName) {
const lotNamePieces = filters.lotName.toLowerCase().split(" ");
for (const lotNamePiece of lotNamePieces) {
sqlWhereClause += " and instr(lower(l.lotName), ?)";
sqlParameters.push(lotNamePiece);
}
}
if (filters.mapId) { if (filters.mapId) {
sqlWhereClause += " and l.mapId = ?"; sqlWhereClause += " and l.mapId = ?";
sqlParameters.push(filters.mapId); sqlParameters.push(filters.mapId);
@ -42,21 +54,32 @@ export const getLots = (filters ? : GetLotsFilters, options?: GetLotsOptions): r
sqlParameters.push(filters.lotStatusId); sqlParameters.push(filters.lotStatusId);
} }
const currentDate = dateToInteger(new Date());
const lots: recordTypes.Lot[] = database const lots: recordTypes.Lot[] = database
.prepare("select l.lotId, l.lotName," + .prepare("select l.lotId, l.lotName," +
" t.lotType," + " t.lotType," +
" m.mapName, l.mapKey," + " l.mapId, m.mapName, l.mapKey," +
" s.lotStatus" + " s.lotStatus," +
" ifnull(o.lotOccupancyCount, 0) as lotOccupancyCount" +
" from Lots l" + " from Lots l" +
" left join LotTypes t on l.lotTypeId = t.lotTypeId" + " left join LotTypes t on l.lotTypeId = t.lotTypeId" +
" left join LotStatuses s on l.lotStatusId = s.lotStatusId" + " left join LotStatuses s on l.lotStatusId = s.lotStatusId" +
" left join Maps m on l.mapId = m.mapId" + " left join Maps m on l.mapId = m.mapId" +
(" left join (" +
"select lotId, count(lotOccupancyId) as lotOccupancyCount" +
" from LotOccupancies" +
" where recordDelete_timeMillis is null" +
" and occupancyStartDate <= " + currentDate +
" and (occupancyEndDate is null or occupancyEndDate >= " + currentDate + ")" +
" group by lotId" +
") o on l.lotId = o.lotId") +
" where l.recordDelete_timeMillis is null" + " where l.recordDelete_timeMillis is null" +
sqlWhereClause + sqlWhereClause +
" order by l.lotName" + " order by l.lotName" +
(options (options ?
? " limit " + options.limit + " offset " + options.offset " limit " + options.limit + " offset " + options.offset :
: "")) ""))
.all(sqlParameters); .all(sqlParameters);
database.close(); database.close();

13
package-lock.json generated
View File

@ -55,6 +55,7 @@
"@types/session-file-store": "^1.2.2", "@types/session-file-store": "^1.2.2",
"@typescript-eslint/eslint-plugin": "^5.30.6", "@typescript-eslint/eslint-plugin": "^5.30.6",
"@typescript-eslint/parser": "^5.30.6", "@typescript-eslint/parser": "^5.30.6",
"bulma": "^0.9.4",
"eslint": "^8.19.0", "eslint": "^8.19.0",
"eslint-plugin-import": "^2.26.0", "eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
@ -2059,6 +2060,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/bulma": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz",
"integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==",
"dev": true
},
"node_modules/bytes": { "node_modules/bytes": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@ -12172,6 +12179,12 @@
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
"dev": true "dev": true
}, },
"bulma": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz",
"integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==",
"dev": true
},
"bytes": { "bytes": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",

View File

@ -74,6 +74,7 @@
"@types/session-file-store": "^1.2.2", "@types/session-file-store": "^1.2.2",
"@typescript-eslint/eslint-plugin": "^5.30.6", "@typescript-eslint/eslint-plugin": "^5.30.6",
"@typescript-eslint/parser": "^5.30.6", "@typescript-eslint/parser": "^5.30.6",
"bulma": "^0.9.4",
"eslint": "^8.19.0", "eslint": "^8.19.0",
"eslint-plugin-import": "^2.26.0", "eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",

View File

@ -1,4 +1,5 @@
@use '../node_modules/@cityssm/bulma-webapp-css/cityssm.min.css'; @use '../node_modules/@cityssm/bulma-webapp-css/cityssm.min.css';
@import '../node_modules/bulma/sass/utilities/derived-variables.sass';
$white: #fff; $white: #fff;
$black: #000; $black: #000;
@ -83,3 +84,26 @@ fieldset:enabled .is-hidden-enabled {
border: 0; border: 0;
} }
} }
/*
* SVG
*/
.image svg {
display: block;
height: auto;
width: 100%;
.highlight,
.highlight path {
&.is-danger {
fill: $danger-light;
}
&.is-success {
fill: $success-light;
}
}
}

View File

@ -20,21 +20,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
for (const lot of responseJSON.lots) { for (const lot of responseJSON.lots) {
resultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" + resultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" +
("<td>" + ("<td>" +
"<a href=\"" + urlPrefix + "/lots/" + lot.lotId + "\">" + "<a class=\"has-text-weight-bold\" href=\"" + urlPrefix + "/lots/" + lot.lotId + "\">" +
lot.lotName + lot.lotName +
"</a>" + "</a>" +
"</td>") + "</td>") +
("<td>" +
"<a href=\"" + urlPrefix + "/maps/" + lot.mapId + "\">" +
lot.mapName +
"</a>" +
"</td>") +
"<td>" + lot.lotType + "</td>" + "<td>" + lot.lotType + "</td>" +
"<td>" + lot.lotStatus + "</td>" + ("<td>" +
"<td>" + lot.mapName + "</td>" + lot.lotStatus + "<br />" +
(lot.lotOccupancyCount > 0 ? "<span class=\"is-size-7\">Currently Occupied</span>" : "") +
"</td>") +
"</tr>"); "</tr>");
} }
searchResultsContainerElement.innerHTML = "<table class=\"table is-fullwidth is-striped is-hoverable\">" + searchResultsContainerElement.innerHTML = "<table class=\"table is-fullwidth is-striped is-hoverable\">" +
"<thead><tr>" + "<thead><tr>" +
"<th>" + exports.aliases.lot + "</th>" + "<th>" + exports.aliases.lot + "</th>" +
"<th>" + exports.aliases.map + "</th>" +
"<th>" + exports.aliases.lot + " Type</th>" + "<th>" + exports.aliases.lot + " Type</th>" +
"<th>Status</th>" + "<th>Status</th>" +
"<th>" + exports.aliases.map + "</th>" +
"</tr></thead>"; "</tr></thead>";
searchResultsContainerElement.querySelector("table").append(resultsTbodyElement); searchResultsContainerElement.querySelector("table").append(resultsTbodyElement);
}); });

View File

@ -41,22 +41,29 @@ declare const cityssm: cityssmGlobal;
for (const lot of responseJSON.lots) { for (const lot of responseJSON.lots) {
resultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" + resultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" +
("<td>" + ("<td>" +
"<a href=\"" + urlPrefix + "/lots/" + lot.lotId + "\">" + "<a class=\"has-text-weight-bold\" href=\"" + urlPrefix + "/lots/" + lot.lotId + "\">" +
lot.lotName + lot.lotName +
"</a>" + "</a>" +
"</td>") + "</td>") +
("<td>" +
"<a href=\"" + urlPrefix + "/maps/" + lot.mapId + "\">" +
lot.mapName +
"</a>" +
"</td>") +
"<td>" + lot.lotType + "</td>" + "<td>" + lot.lotType + "</td>" +
"<td>" + lot.lotStatus + "</td>" + ("<td>" +
"<td>" + lot.mapName + "</td>" + lot.lotStatus + "<br />" +
(lot.lotOccupancyCount > 0 ? "<span class=\"is-size-7\">Currently Occupied</span>" : "") +
"</td>") +
"</tr>"); "</tr>");
} }
searchResultsContainerElement.innerHTML = "<table class=\"table is-fullwidth is-striped is-hoverable\">" + searchResultsContainerElement.innerHTML = "<table class=\"table is-fullwidth is-striped is-hoverable\">" +
"<thead><tr>" + "<thead><tr>" +
"<th>" + exports.aliases.lot + "</th>" + "<th>" + exports.aliases.lot + "</th>" +
"<th>" + exports.aliases.map + "</th>" +
"<th>" + exports.aliases.lot + " Type</th>" + "<th>" + exports.aliases.lot + " Type</th>" +
"<th>Status</th>" + "<th>Status</th>" +
"<th>" + exports.aliases.map + "</th>" +
"</tr></thead>"; "</tr></thead>";
searchResultsContainerElement.querySelector("table").append(resultsTbodyElement); searchResultsContainerElement.querySelector("table").append(resultsTbodyElement);

1
public-typescript/lotView.d.ts vendored 100644
View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const mapContainerElement = document.querySelector("#lot--map");
if (mapContainerElement) {
exports.los.highlightMap(mapContainerElement, mapContainerElement.dataset.mapKey, "success");
}
})();

View File

@ -0,0 +1,11 @@
/* eslint-disable unicorn/prefer-module */
import * as globalTypes from "../types/globalTypes";
(() => {
const mapContainerElement = document.querySelector("#lot--map") as HTMLElement;
if (mapContainerElement) {
(exports.los as globalTypes.LOS).highlightMap(mapContainerElement, mapContainerElement.dataset.mapKey, "success");
}
})();

1
public-typescript/main.d.ts vendored 100644
View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const highlightMap = (mapContainerElement, mapKey, contextualClass) => {
let svgId = mapKey;
let svgElementToHighlight;
while (true) {
svgElementToHighlight = mapContainerElement.querySelector("#" + svgId);
if (svgElementToHighlight || !svgId.includes("-")) {
break;
}
svgId = svgId.slice(0, Math.max(0, svgId.lastIndexOf("-")));
console.log(svgId);
}
if (svgElementToHighlight) {
svgElementToHighlight.style.fill = null;
svgElementToHighlight.classList.add("highlight", "is-" + contextualClass);
const childPathElements = svgElementToHighlight.querySelectorAll("path");
for (const pathElement of childPathElements) {
pathElement.style.fill = null;
}
}
};
const los = {
highlightMap
};
exports.los = los;
})();

View File

@ -0,0 +1,49 @@
/* eslint-disable unicorn/prefer-module */
import type * as globalTypes from "../types/globalTypes";
(() => {
const highlightMap = (mapContainerElement: HTMLElement, mapKey: string, contextualClass: "success" | "danger") => {
// Search for ID
let svgId = mapKey;
let svgElementToHighlight: SVGElement;
// eslint-disable-next-line no-constant-condition
while(true) {
svgElementToHighlight = mapContainerElement.querySelector("#" + svgId);
if (svgElementToHighlight || !svgId.includes("-")) {
break;
}
svgId = svgId.slice(0, Math.max(0, svgId.lastIndexOf("-")));
console.log(svgId);
}
if (svgElementToHighlight) {
// eslint-disable-next-line unicorn/no-null
svgElementToHighlight.style.fill = null;
svgElementToHighlight.classList.add("highlight", "is-" + contextualClass);
const childPathElements = svgElementToHighlight.querySelectorAll("path");
for (const pathElement of childPathElements) {
// eslint-disable-next-line unicorn/no-null
pathElement.style.fill = null;
}
}
};
const los: globalTypes.LOS = {
highlightMap
};
exports.los = los;
})();

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 451 KiB

After

Width:  |  Height:  |  Size: 503 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 384 KiB

After

Width:  |  Height:  |  Size: 480 KiB

View File

@ -1 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,t=document.querySelector("#form--searchFilters"),s=document.querySelector("#container--searchResults"),a=()=>{s.innerHTML='<div class="has-text-grey has-text-centered"><i class="fas fa-5x fa-circle-notch fa-spin" aria-hidden="true"></i><br />Loading '+exports.aliases.lots+"...</div>",cityssm.postJSON(e+"/lots/doSearchLots",t,t=>{if(0===t.lots.length)return void(s.innerHTML='<div class="message is-info"><p class="message-body">There are no '+exports.aliases.lots.toLowerCase()+" that meet the search criteria.</p></div>");const a=document.createElement("tbody");for(const s of t.lots)a.insertAdjacentHTML("beforeend",'<tr><td><a href="'+e+"/lots/"+s.lotId+'">'+s.lotName+"</a></td><td>"+s.lotType+"</td><td>"+s.lotStatus+"</td><td>"+s.mapName+"</td></tr>");s.innerHTML='<table class="table is-fullwidth is-striped is-hoverable"><thead><tr><th>'+exports.aliases.lot+"</th><th>"+exports.aliases.lot+" Type</th><th>Status</th><th>"+exports.aliases.map+"</th></tr></thead>",s.querySelector("table").append(a)})},r=t.querySelectorAll("input, select");for(const e of r)e.addEventListener("change",a);t.addEventListener("submit",e=>{e.preventDefault(),a()}),a()})(); "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,t=document.querySelector("#form--searchFilters"),s=document.querySelector("#container--searchResults"),a=()=>{s.innerHTML='<div class="has-text-grey has-text-centered"><i class="fas fa-5x fa-circle-notch fa-spin" aria-hidden="true"></i><br />Loading '+exports.aliases.lots+"...</div>",cityssm.postJSON(e+"/lots/doSearchLots",t,t=>{if(0===t.lots.length)return void(s.innerHTML='<div class="message is-info"><p class="message-body">There are no '+exports.aliases.lots.toLowerCase()+" that meet the search criteria.</p></div>");const a=document.createElement("tbody");for(const s of t.lots)a.insertAdjacentHTML("beforeend",'<tr><td><a class="has-text-weight-bold" href="'+e+"/lots/"+s.lotId+'">'+s.lotName+'</a></td><td><a href="'+e+"/maps/"+s.mapId+'">'+s.mapName+"</a></td><td>"+s.lotType+"</td><td>"+s.lotStatus+"<br />"+(s.lotOccupancyCount>0?'<span class="is-size-7">Currently Occupied</span>':"")+"</td></tr>");s.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></tr></thead>",s.querySelector("table").append(a)})},r=t.querySelectorAll("input, select");for(const e of r)e.addEventListener("change",a);t.addEventListener("submit",e=>{e.preventDefault(),a()}),a()})();

View File

@ -0,0 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("#lot--map");e&&exports.los.highlightMap(e,e.dataset.mapKey,"success")})();

1
public/javascripts/main.min.js vendored 100644
View File

@ -0,0 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const l={highlightMap:(l,e,t)=>{let s,o=e;for(;!(s=l.querySelector("#"+o))&&o.includes("-");)o=o.slice(0,Math.max(0,o.lastIndexOf("-"))),console.log(o);if(s){s.style.fill=null,s.classList.add("highlight","is-"+t);const l=s.querySelectorAll("path");for(const e of l)e.style.fill=null}}};exports.los=l})();

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@ export const router = Router();
router.get("/", handler_search); router.get("/", handler_search);
router.post("/doSearchLots", handler_doSearchLots); router.post("/doSearchLots", handler_doSearchLots);
router.get("/new", permissionHandlers.updateGetHandler, handler_new); router.get("/new", permissionHandlers.updateGetHandler, handler_new);
router.get("/:licenceID", handler_view); router.get("/:lotId", handler_view);
router.get("/:licenceID/edit", permissionHandlers.updateGetHandler, handler_edit); router.get("/:lotId/edit", permissionHandlers.updateGetHandler, handler_edit);
router.get("/:licenceID/print", handler_print); router.get("/:lotId/print", handler_print);
export default router; export default router;

View File

@ -37,16 +37,16 @@ router.get("/new",
router.get("/:licenceID", router.get("/:lotId",
handler_view); handler_view);
router.get("/:licenceID/edit", router.get("/:lotId/edit",
permissionHandlers.updateGetHandler, permissionHandlers.updateGetHandler,
handler_edit); handler_edit);
router.get("/:licenceID/print", router.get("/:lotId/print",
handler_print); handler_print);

View File

@ -101,9 +101,13 @@ function importFromCSV() {
const map = getMap(masterRow); const map = getMap(masterRow);
const lotName = masterRow.CM_CEMETERY + "-" + const lotName = masterRow.CM_CEMETERY + "-" +
(masterRow.CM_BLOCK === "" ? "" : masterRow.CM_BLOCK + "-") + (masterRow.CM_BLOCK === "" ? "" : masterRow.CM_BLOCK + "-") +
(masterRow.CM_RANGE2 === "" ? masterRow.CM_RANGE1 : masterRow.CM_RANGE2) + "-" + (masterRow.CM_RANGE1 === "0" && masterRow.CM_RANGE2 === "" ?
(masterRow.CM_LOT2 === "" ? masterRow.CM_LOT1 : masterRow.CM_LOT2) + "-" + "" :
(masterRow.CM_GRAVE2 === "" ? masterRow.CM_GRAVE1 : masterRow.CM_GRAVE2) + "-" + (masterRow.CM_RANGE2 === "" ?
masterRow.CM_RANGE1 :
masterRow.CM_RANGE2) + "-") +
masterRow.CM_LOT1 + masterRow.CM_LOT2 + "-" +
masterRow.CM_GRAVE1 + masterRow.CM_GRAVE2 + "-" +
masterRow.CM_INTERMENT; masterRow.CM_INTERMENT;
const lotId = addLot({ const lotId = addLot({
lotName: lotName, lotName: lotName,
@ -122,9 +126,9 @@ function importFromCSV() {
occupantCity: masterRow.CM_CITY, occupantCity: masterRow.CM_CITY,
occupantPostalCode occupantPostalCode
}); });
const occupantId = possibleOccupants.length > 0 const occupantId = possibleOccupants.length > 0 ?
? possibleOccupants[0].occupantId possibleOccupants[0].occupantId :
: addOccupant({ addOccupant({
occupantName: masterRow.CM_PRENEED_ORDER, occupantName: masterRow.CM_PRENEED_ORDER,
occupantAddress1: masterRow.CM_ADDRESS, occupantAddress1: masterRow.CM_ADDRESS,
occupantAddress2: "", occupantAddress2: "",

View File

@ -4,20 +4,38 @@ import fs from "node:fs";
import papa from "papaparse"; import papa from "papaparse";
import sqlite from "better-sqlite3"; import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../data/databasePaths.js"; import {
lotOccupancyDB as databasePath
} from "../data/databasePaths.js";
import * as cacheFunctions from "../helpers/functions.cache.js"; import * as cacheFunctions from "../helpers/functions.cache.js";
import { addMap } from "../helpers/lotOccupancyDB/addMap.js"; import {
import { getMap as getMapFromDatabase } from "../helpers/lotOccupancyDB/getMap.js"; addMap
} from "../helpers/lotOccupancyDB/addMap.js";
import {
getMap as getMapFromDatabase
} from "../helpers/lotOccupancyDB/getMap.js";
import { addLot } from "../helpers/lotOccupancyDB/addLot.js"; import {
import { updateLotStatus } from "../helpers/lotOccupancyDB/updateLot.js"; addLot
} from "../helpers/lotOccupancyDB/addLot.js";
import {
updateLotStatus
} from "../helpers/lotOccupancyDB/updateLot.js";
import { getOccupants } from "../helpers/lotOccupancyDB/getOccupants.js"; import {
import { addOccupant } from "../helpers/lotOccupancyDB/addOccupant.js"; getOccupants
import { addLotOccupancy } from "../helpers/lotOccupancyDB/addLotOccupancy.js"; } from "../helpers/lotOccupancyDB/getOccupants.js";
import { addLotOccupancyOccupant } from "../helpers/lotOccupancyDB/addLotOccupancyOccupant.js"; import {
addOccupant
} from "../helpers/lotOccupancyDB/addOccupant.js";
import {
addLotOccupancy
} from "../helpers/lotOccupancyDB/addLotOccupancy.js";
import {
addLotOccupancyOccupant
} from "../helpers/lotOccupancyDB/addLotOccupancyOccupant.js";
import type * as recordTypes from "../types/recordTypes"; import type * as recordTypes from "../types/recordTypes";
@ -200,9 +218,13 @@ function importFromCSV () {
const lotName = masterRow.CM_CEMETERY + "-" + const lotName = masterRow.CM_CEMETERY + "-" +
(masterRow.CM_BLOCK === "" ? "" : masterRow.CM_BLOCK + "-") + (masterRow.CM_BLOCK === "" ? "" : masterRow.CM_BLOCK + "-") +
(masterRow.CM_RANGE2 === "" ? masterRow.CM_RANGE1 : masterRow.CM_RANGE2) + "-" + (masterRow.CM_RANGE1 === "0" && masterRow.CM_RANGE2 === "" ?
(masterRow.CM_LOT2 === "" ? masterRow.CM_LOT1 : masterRow.CM_LOT2) + "-" + "" :
(masterRow.CM_GRAVE2 === "" ? masterRow.CM_GRAVE1 : masterRow.CM_GRAVE2) + "-" + (masterRow.CM_RANGE2 === "" ?
masterRow.CM_RANGE1 :
masterRow.CM_RANGE2) + "-") +
masterRow.CM_LOT1 + masterRow.CM_LOT2 + "-" +
masterRow.CM_GRAVE1 + masterRow.CM_GRAVE2 + "-" +
masterRow.CM_INTERMENT; masterRow.CM_INTERMENT;
const lotId = addLot({ const lotId = addLot({
@ -226,9 +248,9 @@ function importFromCSV () {
occupantPostalCode occupantPostalCode
}); });
const occupantId = possibleOccupants.length > 0 const occupantId = possibleOccupants.length > 0 ?
? possibleOccupants[0].occupantId possibleOccupants[0].occupantId :
: addOccupant({ addOccupant({
occupantName: masterRow.CM_PRENEED_ORDER, occupantName: masterRow.CM_PRENEED_ORDER,
occupantAddress1: masterRow.CM_ADDRESS, occupantAddress1: masterRow.CM_ADDRESS,
occupantAddress2: "", occupantAddress2: "",

View File

@ -18,8 +18,6 @@ export interface Config {
lots: string; lots: string;
map: string; map: string;
maps: string; maps: string;
occupancy: string;
occupancies: string;
}; };
} }
interface ConfigApplication { interface ConfigApplication {

View File

@ -18,8 +18,6 @@ export interface Config {
lots: string; lots: string;
map: string; map: string;
maps: string; maps: string;
occupancy: string;
occupancies: string;
} }
} }

3
types/globalTypes.d.ts vendored 100644
View File

@ -0,0 +1,3 @@
export interface LOS {
highlightMap: (mapContainerElement: HTMLElement, mapKey: string, contextualClass: "success" | "danger") => void;
}

View File

@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@ -0,0 +1,3 @@
export interface LOS {
highlightMap: (mapContainerElement: HTMLElement, mapKey: string, contextualClass: "success" | "danger") => void;
}

View File

@ -56,11 +56,13 @@ export interface Lot extends Record {
mapId?: number; mapId?: number;
mapName?: string; mapName?: string;
map?: Map; map?: Map;
mapSVG?: string;
mapKey?: string; mapKey?: string;
lotLatitude?: number; lotLatitude?: number;
lotLongitude?: number; lotLongitude?: number;
lotStatusId?: number; lotStatusId?: number;
lotStatus?: LotStatus | string; lotStatus?: LotStatus | string;
lotOccupancyCount?: number;
} }
export interface OccupancyType extends Record { export interface OccupancyType extends Record {
occupancyTypeId?: number; occupancyTypeId?: number;

View File

@ -1,2 +1 @@
"use strict"; export {};
Object.defineProperty(exports, "__esModule", { value: true });

View File

@ -81,6 +81,7 @@ export interface Lot extends Record {
mapId?: number; mapId?: number;
mapName?: string; mapName?: string;
map?: Map; map?: Map;
mapSVG?: string;
mapKey?: string; mapKey?: string;
lotLatitude?: number; lotLatitude?: number;
@ -88,6 +89,8 @@ export interface Lot extends Record {
lotStatusId?: number; lotStatusId?: number;
lotStatus?: LotStatus | string; lotStatus?: LotStatus | string;
lotOccupancyCount?: number;
} }

View File

@ -29,3 +29,4 @@
</script> </script>
<script src="<%= urlPrefix %>/lib/cityssm-bulma-webapp-js/dist/cityssm-theme.min.js" defer></script> <script src="<%= urlPrefix %>/lib/cityssm-bulma-webapp-js/dist/cityssm-theme.min.js" defer></script>
<script src="<%= urlPrefix %>/lib/fa/js/all.min.js" defer></script> <script src="<%= urlPrefix %>/lib/fa/js/all.min.js" defer></script>
<script src="<%= urlPrefix %>/javascripts/main.min.js"></script>

View File

@ -53,9 +53,9 @@
</div> </div>
<div class="media-content has-text-black"> <div class="media-content has-text-black">
<h2 class="title is-4 is-marginless"> <h2 class="title is-4 is-marginless">
<a href="<%= urlPrefix %>/lotOccupancies"><%= configFunctions.getProperty("aliases.lot") + " " + configFunctions.getProperty("aliases.occupancies") %></a> <a href="<%= urlPrefix %>/lotOccupancies"><%= configFunctions.getProperty("aliases.lot") %> Occupancies</a>
</h2> </h2>
<p>View and maintain <%= configFunctions.getProperty("aliases.lot").toLowerCase() + " " + configFunctions.getProperty("aliases.occupancies").toLowerCase() %>.</p> <p>View and maintain <%= configFunctions.getProperty("aliases.lot").toLowerCase() %> occupancies.</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -30,18 +30,9 @@
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="searchFilter--mapId"><%= configFunctions.getProperty("aliases.map") %></label> <label class="label" for="searchFilter--lotName"><%= configFunctions.getProperty("aliases.lot") %></label>
<div class="control"> <div class="control">
<div class="select is-fullwidth"> <input class="input" id="searchFilter--lotName" name="lotName" />
<select id="searchFilter--mapId" name="mapId">
<option value="">(All <%= configFunctions.getProperty("aliases.maps") %>)</option>
<% for (const map of maps) { %>
<option value="<%= map.mapId %>" <%= (map.mapId.toString() === mapId) ? " selected" : "" %>>
<%= map.mapName %>
</option>
<% } %>
</select>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -60,6 +51,25 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="columns">
<div class="column">
<div class="field">
<label class="label" for="searchFilter--mapId"><%= configFunctions.getProperty("aliases.map") %></label>
<div class="control">
<div class="select is-fullwidth">
<select id="searchFilter--mapId" name="mapId">
<option value="">(All <%= configFunctions.getProperty("aliases.maps") %>)</option>
<% for (const map of maps) { %>
<option value="<%= map.mapId %>" <%= (map.mapId.toString() === mapId) ? " selected" : "" %>>
<%= map.mapName %>
</option>
<% } %>
</select>
</div>
</div>
</div>
</div>
<div class="column"> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="searchFilter--lotStatusId">Status</label> <label class="label" for="searchFilter--lotStatusId">Status</label>

View File

@ -0,0 +1,47 @@
<%- include('_header'); -%>
<nav class="breadcrumb">
<ul>
<li><a href="<%= urlPrefix %>/dashboard">Home</a></li>
<li>
<a href="<%= urlPrefix %>/lots">
<span class="icon is-small"><i class="fas fa-vector-square" aria-hidden="true"></i></span>
<span><%= configFunctions.getProperty("aliases.lots") %></span>
</a>
</li>
<li class="is-active"><a href="#" aria-current="page">
<span class="icon is-small"><i class="fas fa-vector-square" aria-hidden="true"></i></span>
<span><%= lot.lotName %></span>
</a></li>
</ul>
</nav>
<h1 class="title is-1">
<%= lot.lotName %>
</h1>
<% if (user.userProperties.canUpdate) { %>
<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 <%= configFunctions.getProperty("aliases.lot") %>" href="<%= urlPrefix %>/lots/<%= lot.lotId %>/edit>">
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
<span class="sr-only">Update <%= configFunctions.getProperty("aliases.lot") %></span>
</a>
</div>
<% } %>
<% if (lot.mapSVG) { %>
<% const imageURL = urlPrefix + "/images/maps/" + lot.mapSVG %>
<div class="image" id="lot--map" data-map-key="<%= lot.mapKey %>">
<%- include('../public/images/maps/' + lot.mapSVG); -%>
</div>
<% } else { %>
<div class="message is-info">
<p class="message-body">There are no image associated with this <%= configFunctions.getProperty("aliases.lot").toLowerCase() %>.</p>
</div>
<% } %>
<%- include('_footerA'); -%>
<script src="<%= urlPrefix %>/javascripts/lotView.min.js"></script>
<%- include('_footerB'); -%>

View File

@ -33,12 +33,31 @@
</div> </div>
<% } %> <% } %>
<div class="columns">
<% if (map.mapDescription && map.mapDescription !== "") { %> <% if (map.mapDescription && map.mapDescription !== "") { %>
<div class="mb-2"> <div class="column">
<strong>Description</strong><br /> <strong>Description</strong><br />
<%= map.mapDescription %> <%= map.mapDescription %>
</div> </div>
<% } %> <% } %>
<div class="column">
<strong>Address</strong><br />
<% if (map.mapAddress1 !== "") { %>
<%= map.mapAddress1 %><br />
<% } %>
<% if (map.mapAddress2 !== "") { %>
<%= map.mapAddress2 %><br />
<% } %>
<%= map.mapCity %>, <%= map.mapProvince %><br />
<%= map.mapPostalCode %>
</div>
</div>
<% if (map.mapPhoneNumber !== "") { %>
<div class="column">
<strong>Phone Number</strong><br />
<%= map.mapPhoneNumber %>
</div>
<% } %>
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
@ -54,13 +73,10 @@
</div> </div>
<div class="column"> <div class="column">
<h2 class="title is-4">Image</h2> <h2 class="title is-4">Image</h2>
<% if (map.mapSVG) { %> <% if (map.mapSVG) { %>
<div class="image">
<% const imageURL = urlPrefix + "/images/maps/" + map.mapSVG %> <% const imageURL = urlPrefix + "/images/maps/" + map.mapSVG %>
<a href="<%= imageURL %>" target="_blank" title="Open in New Window"> <div class="image">
<img src="<%= imageURL %>" alt="<%= configFunctions.getProperty("aliases.map") %> Image" /> <%- include('../public/images/maps/' + map.mapSVG); -%>
</a>
</div> </div>
<% } else { %> <% } else { %>
<div class="message is-info"> <div class="message is-info">