development

Highlights
- application map create and update
- map file renaming, again
- more importing
deepsource-autofix-76c6eb20
Dan Gowans 2022-07-20 16:22:08 -04:00
parent 91e49fdbaa
commit 012362c07b
143 changed files with 1030 additions and 90 deletions

View File

@ -1,13 +1,16 @@
import * as configFunctions from "../../helpers/functions.config.js"; import * as configFunctions from "../../helpers/functions.config.js";
import { getMaps } from "../../helpers/lotOccupancyDB/getMaps.js"; import { getMaps } from "../../helpers/lotOccupancyDB/getMaps.js";
import { getLotTypes } from "../../helpers/lotOccupancyDB/getLotTypes.js"; import { getLotTypes, getLotStatuses } from "../../helpers/functions.cache.js";
export const handler = (_request, response) => { export const handler = (request, response) => {
const maps = getMaps(); const maps = getMaps();
const lotTypes = getLotTypes(); const lotTypes = getLotTypes();
const lotStatuses = getLotStatuses();
response.render("lot-search", { response.render("lot-search", {
headTitle: configFunctions.getProperty("aliases.lot") + " Search", headTitle: configFunctions.getProperty("aliases.lot") + " Search",
maps, maps,
lotTypes lotTypes,
lotStatuses,
mapId: request.query.mapId
}); });
}; };
export default handler; export default handler;

View File

@ -8,18 +8,21 @@ import {
getMaps getMaps
} from "../../helpers/lotOccupancyDB/getMaps.js"; } from "../../helpers/lotOccupancyDB/getMaps.js";
import { getLotTypes } from "../../helpers/lotOccupancyDB/getLotTypes.js"; import { getLotTypes, getLotStatuses } from "../../helpers/functions.cache.js";
export const handler: RequestHandler = (_request, response) => { export const handler: RequestHandler = (request, response) => {
const maps = getMaps(); const maps = getMaps();
const lotTypes = getLotTypes(); const lotTypes = getLotTypes();
const lotStatuses = getLotStatuses();
response.render("lot-search", { response.render("lot-search", {
headTitle: configFunctions.getProperty("aliases.lot") + " Search", headTitle: configFunctions.getProperty("aliases.lot") + " Search",
maps, maps,
lotTypes lotTypes,
lotStatuses,
mapId: request.query.mapId
}); });
}; };

View File

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

View File

@ -0,0 +1,11 @@
import { getLots } from "../../helpers/lotOccupancyDB/getLots.js";
export const handler = async (request, response) => {
const lots = getLots(request.body, {
limit: request.body.limit,
offset: request.body.offset
});
response.json({
lots
});
};
export default handler;

View File

@ -0,0 +1,19 @@
import type { RequestHandler } from "express";
import { getLots } from "../../helpers/lotOccupancyDB/getLots.js";
export const handler: RequestHandler = async (request, response) => {
const lots = getLots(request.body, {
limit: request.body.limit,
offset: request.body.offset
});
response.json({
lots
});
};
export default handler;

3
handlers/maps-get/edit.d.ts vendored 100644
View File

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

View File

@ -0,0 +1,17 @@
import * as configFunctions from "../../helpers/functions.config.js";
import { getMap } from "../../helpers/lotOccupancyDB/getMap.js";
import { getMapSVGs } from "../../helpers/functions.map.js";
export const handler = async (request, response) => {
const map = getMap(request.params.mapId);
if (!map) {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound");
}
const mapSVGs = await getMapSVGs();
response.render("map-edit", {
headTitle: map.mapName,
isCreate: false,
map,
mapSVGs
});
};
export default handler;

View File

@ -0,0 +1,29 @@
import type { RequestHandler } from "express";
import * as configFunctions from "../../helpers/functions.config.js";
import { getMap } from "../../helpers/lotOccupancyDB/getMap.js";
import { getMapSVGs } from "../../helpers/functions.map.js";
export const handler: RequestHandler = async (request, response) => {
const map = getMap(request.params.mapId);
if (!map) {
return response.redirect(configFunctions.getProperty("reverseProxy.urlPrefix") + "/maps/?error=mapIdNotFound");
}
const mapSVGs = await getMapSVGs();
response.render("map-edit", {
headTitle: map.mapName,
isCreate: false,
map,
mapSVGs
});
};
export default handler;

View File

@ -1,10 +1,13 @@
import * as configFunctions from "../../helpers/functions.config.js"; import * as configFunctions from "../../helpers/functions.config.js";
export const handler = (_request, response) => { import { getMapSVGs } from "../../helpers/functions.map.js";
export const handler = async (_request, response) => {
const map = {}; const map = {};
const mapSVGs = await getMapSVGs();
response.render("map-edit", { response.render("map-edit", {
headTitle: configFunctions.getProperty("aliases.map") + " Create", headTitle: configFunctions.getProperty("aliases.map") + " Create",
isCreate: true, isCreate: true,
map map,
mapSVGs
}); });
}; };
export default handler; export default handler;

View File

@ -1,18 +1,22 @@
import type { RequestHandler } from "express"; import type { RequestHandler } from "express";
import * as configFunctions from "../../helpers/functions.config.js"; import * as configFunctions from "../../helpers/functions.config.js";
import { getMapSVGs } from "../../helpers/functions.map.js";
import * as recordTypes from "../../types/recordTypes"; import * as recordTypes from "../../types/recordTypes";
export const handler: RequestHandler = (_request, response) => { export const handler: RequestHandler = async (_request, response) => {
const map: recordTypes.Map = {}; const map: recordTypes.Map = {};
const mapSVGs = await getMapSVGs();
response.render("map-edit", { response.render("map-edit", {
headTitle: configFunctions.getProperty("aliases.map") + " Create", headTitle: configFunctions.getProperty("aliases.map") + " Create",
isCreate: true, isCreate: true,
map map,
mapSVGs
}); });
}; };

View File

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

View File

@ -0,0 +1,9 @@
import { addMap } from "../../helpers/lotOccupancyDB/addMap.js";
export const handler = async (request, response) => {
const mapId = addMap(request.body, request.session);
response.json({
success: true,
mapId
});
};
export default handler;

View File

@ -0,0 +1,17 @@
import type { RequestHandler } from "express";
import { addMap } from "../../helpers/lotOccupancyDB/addMap.js";
export const handler: RequestHandler = async (request, response) => {
const mapId = addMap(request.body, request.session);
response.json({
success: true,
mapId
});
};
export default handler;

View File

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

View File

@ -0,0 +1,9 @@
import { updateMap } from "../../helpers/lotOccupancyDB/updateMap.js";
export const handler = async (request, response) => {
const success = updateMap(request.body, request.session);
response.json({
success,
mapId: request.body.mapId
});
};
export default handler;

View File

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

1
helpers/functions.map.d.ts vendored 100644
View File

@ -0,0 +1 @@
export declare function getMapSVGs(): Promise<string[]>;

View File

@ -0,0 +1,15 @@
import fs from "node:fs/promises";
let mapSVGs;
export async function getMapSVGs() {
if (!mapSVGs) {
const files = await fs.readdir("./public/images/maps/");
const SVGs = [];
for (const file of files) {
if (file.toLowerCase().endsWith(".svg")) {
SVGs.push(file);
}
}
mapSVGs = SVGs;
}
return mapSVGs;
}

View File

@ -0,0 +1,23 @@
import fs from "node:fs/promises";
let mapSVGs: string[];
export async function getMapSVGs () {
if (!mapSVGs) {
const files = await fs.readdir("./public/images/maps/");
const SVGs: string[] = [];
for (const file of files) {
if (file.toLowerCase().endsWith(".svg")) {
SVGs.push(file);
}
}
mapSVGs = SVGs;
}
return mapSVGs;
}

View File

@ -4,6 +4,10 @@ import * as dateTimeFunctions from "@cityssm/expressjs-server-js/dateTimeFns.js"
export const addLotOccupancy = (lotOccupancyForm, requestSession) => { export const addLotOccupancy = (lotOccupancyForm, requestSession) => {
const database = sqlite(databasePath); const database = sqlite(databasePath);
const rightNowMillis = Date.now(); const rightNowMillis = Date.now();
const occupancyStartDate = dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyStartDateString);
if (occupancyStartDate <= 0) {
console.error(lotOccupancyForm);
}
const result = database const result = database
.prepare("insert into LotOccupancies (" + .prepare("insert into LotOccupancies (" +
"occupancyTypeId, lotId," + "occupancyTypeId, lotId," +
@ -11,7 +15,7 @@ export const addLotOccupancy = (lotOccupancyForm, requestSession) => {
" recordCreate_userName, recordCreate_timeMillis," + " recordCreate_userName, recordCreate_timeMillis," +
" recordUpdate_userName, recordUpdate_timeMillis)" + " recordUpdate_userName, recordUpdate_timeMillis)" +
" values (?, ?, ?, ?, ?, ?, ?, ?)") " values (?, ?, ?, ?, ?, ?, ?, ?)")
.run(lotOccupancyForm.occupancyTypeId, lotOccupancyForm.lotId, dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyStartDateString), (lotOccupancyForm.occupancyEndDateString === "" .run(lotOccupancyForm.occupancyTypeId, lotOccupancyForm.lotId, occupancyStartDate, (lotOccupancyForm.occupancyEndDateString === ""
? undefined ? undefined
: dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyEndDateString)), requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis); : dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyEndDateString)), requestSession.user.userName, rightNowMillis, requestSession.user.userName, rightNowMillis);
database.close(); database.close();

View File

@ -22,6 +22,12 @@ export const addLotOccupancy =
const rightNowMillis = Date.now(); const rightNowMillis = Date.now();
const occupancyStartDate = dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyStartDateString);
if (occupancyStartDate <= 0) {
console.error(lotOccupancyForm);
}
const result = database const result = database
.prepare("insert into LotOccupancies (" + .prepare("insert into LotOccupancies (" +
"occupancyTypeId, lotId," + "occupancyTypeId, lotId," +
@ -31,7 +37,7 @@ export const addLotOccupancy =
" values (?, ?, ?, ?, ?, ?, ?, ?)") " values (?, ?, ?, ?, ?, ?, ?, ?)")
.run(lotOccupancyForm.occupancyTypeId, .run(lotOccupancyForm.occupancyTypeId,
lotOccupancyForm.lotId, lotOccupancyForm.lotId,
dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyStartDateString), occupancyStartDate,
(lotOccupancyForm.occupancyEndDateString === "" (lotOccupancyForm.occupancyEndDateString === ""
? undefined ? undefined
: dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyEndDateString)), : dateTimeFunctions.dateStringToInteger(lotOccupancyForm.occupancyEndDateString)),

View File

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

View File

@ -10,6 +10,14 @@ export const getLots = (filters, options) => {
sqlWhereClause += " and l.mapId = ?"; sqlWhereClause += " and l.mapId = ?";
sqlParameters.push(filters.mapId); sqlParameters.push(filters.mapId);
} }
if (filters.lotTypeId) {
sqlWhereClause += " and l.lotTypeId = ?";
sqlParameters.push(filters.lotTypeId);
}
if (filters.lotStatusId) {
sqlWhereClause += " and l.lotStatusId = ?";
sqlParameters.push(filters.lotStatusId);
}
const lots = database const lots = database
.prepare("select l.lotId, l.lotName," + .prepare("select l.lotId, l.lotName," +
" t.lotType," + " t.lotType," +

View File

@ -8,6 +8,8 @@ import type * as recordTypes from "../../types/recordTypes";
interface GetLotsFilters { interface GetLotsFilters {
mapId?: number | string; mapId?: number | string;
lotTypeId?: number | string;
lotStatusId?: number | string;
} }
interface GetLotsOptions { interface GetLotsOptions {
@ -30,6 +32,16 @@ export const getLots = (filters ? : GetLotsFilters, options?: GetLotsOptions): r
sqlParameters.push(filters.mapId); sqlParameters.push(filters.mapId);
} }
if (filters.lotTypeId) {
sqlWhereClause += " and l.lotTypeId = ?";
sqlParameters.push(filters.lotTypeId);
}
if (filters.lotStatusId) {
sqlWhereClause += " and l.lotStatusId = ?";
sqlParameters.push(filters.lotStatusId);
}
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," +

View File

@ -8,7 +8,7 @@ export const getMaps = (filters) => {
.prepare("select m.mapId, m.mapName, m.mapDescription," + .prepare("select m.mapId, m.mapName, m.mapDescription," +
" m.mapLatitude, m.mapLongitude, m.mapSVG," + " m.mapLatitude, m.mapLongitude, m.mapSVG," +
" m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," + " m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," +
" l.lotCount" + " ifnull(l.lotCount,0) as lotCount" +
" from Maps m" + " from Maps m" +
(" left join (" + (" left join (" +
"select mapId, count(lotId) as lotCount" + "select mapId, count(lotId) as lotCount" +

View File

@ -21,7 +21,7 @@ export const getMaps = (filters ? : GetMapsFilters): recordTypes.Map[] => {
.prepare("select m.mapId, m.mapName, m.mapDescription," + .prepare("select m.mapId, m.mapName, m.mapDescription," +
" m.mapLatitude, m.mapLongitude, m.mapSVG," + " m.mapLatitude, m.mapLongitude, m.mapSVG," +
" m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," + " m.mapAddress1, m.mapAddress2, m.mapCity, m.mapProvince, m.mapPostalCode, m.mapPhoneNumber," +
" l.lotCount" + " ifnull(l.lotCount,0) as lotCount" +
" from Maps m" + " from Maps m" +
(" left join (" + (" left join (" +
"select mapId, count(lotId) as lotCount" + "select mapId, count(lotId) as lotCount" +

View File

@ -0,0 +1,14 @@
import type * as recordTypes from "../../types/recordTypes";
interface UpdateLotForm {
lotId: string | number;
lotName: string;
lotTypeId: string | number;
lotStatusId: string | number;
mapId: string | number;
mapKey: string;
lotLatitude: string;
lotLongitude: string;
}
export declare function updateLot(lotForm: UpdateLotForm, requestSession: recordTypes.PartialSession): boolean;
export declare function updateLotStatus(lotId: number | string, lotStatusId: number | string, requestSession: recordTypes.PartialSession): boolean;
export default updateLot;

View File

@ -0,0 +1,37 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
export function updateLot(lotForm, requestSession) {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare("update Lots" +
" set lotName = ?," +
" lotTypeId = ?," +
" lotStatusId = ?," +
" mapId = ?," +
" mapKey = ?," +
" lotLatitude = ?," +
" lotLongitude = ?," +
" recordUpdate_userName = ?," +
" recordUpdate_timeMillis = ?" +
" where lotId = ?" +
" and recordDelete_timeMillis is null")
.run(lotForm.lotName, lotForm.lotTypeId, (lotForm.lotStatusId === "" ? undefined : lotForm.lotStatusId), (lotForm.mapId === "" ? undefined : lotForm.mapId), lotForm.mapKey, (lotForm.lotLatitude === "" ? undefined : lotForm.lotLatitude), (lotForm.lotLongitude === "" ? undefined : lotForm.lotLongitude), requestSession.user.userName, rightNowMillis, lotForm.lotId);
database.close();
return result.changes > 0;
}
export function updateLotStatus(lotId, lotStatusId, requestSession) {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare("update Lots" +
" set lotStatusId = ?," +
" recordUpdate_userName = ?," +
" recordUpdate_timeMillis = ?" +
" where lotId = ?" +
" and recordDelete_timeMillis is null")
.run((lotStatusId === "" ? undefined : lotStatusId), requestSession.user.userName, rightNowMillis, lotId);
database.close();
return result.changes > 0;
}
export default updateLot;

View File

@ -0,0 +1,80 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import type * as recordTypes from "../../types/recordTypes";
interface UpdateLotForm {
lotId: string | number;
lotName: string;
lotTypeId: string | number;
lotStatusId: string | number;
mapId: string | number;
mapKey: string;
lotLatitude: string;
lotLongitude: string;
}
export function updateLot(lotForm: UpdateLotForm, requestSession: recordTypes.PartialSession): boolean {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare("update Lots" +
" set lotName = ?," +
" lotTypeId = ?," +
" lotStatusId = ?," +
" mapId = ?," +
" mapKey = ?," +
" lotLatitude = ?," +
" lotLongitude = ?," +
" recordUpdate_userName = ?," +
" recordUpdate_timeMillis = ?" +
" where lotId = ?" +
" and recordDelete_timeMillis is null")
.run(lotForm.lotName,
lotForm.lotTypeId,
(lotForm.lotStatusId === "" ? undefined : lotForm.lotStatusId),
(lotForm.mapId === "" ? undefined : lotForm.mapId),
lotForm.mapKey,
(lotForm.lotLatitude === "" ? undefined : lotForm.lotLatitude),
(lotForm.lotLongitude === "" ? undefined : lotForm.lotLongitude),
requestSession.user.userName,
rightNowMillis,
lotForm.lotId);
database.close();
return result.changes > 0;
}
export function updateLotStatus(lotId: number | string, lotStatusId: number | string, requestSession: recordTypes.PartialSession): boolean {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare("update Lots" +
" set lotStatusId = ?," +
" recordUpdate_userName = ?," +
" recordUpdate_timeMillis = ?" +
" where lotId = ?" +
" and recordDelete_timeMillis is null")
.run((lotStatusId === "" ? undefined : lotStatusId),
requestSession.user.userName,
rightNowMillis,
lotId);
database.close();
return result.changes > 0;
}
export default updateLot;

View File

@ -0,0 +1,17 @@
import type * as recordTypes from "../../types/recordTypes";
interface UpdateMapForm {
mapId: string;
mapName: string;
mapDescription: string;
mapSVG: string;
mapLatitude: string;
mapLongitude: string;
mapAddress1: string;
mapAddress2: string;
mapCity: string;
mapProvince: string;
mapPostalCode: string;
mapPhoneNumber: string;
}
export declare const updateMap: (mapForm: UpdateMapForm, requestSession: recordTypes.PartialSession) => boolean;
export default updateMap;

View File

@ -0,0 +1,27 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
export const updateMap = (mapForm, requestSession) => {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare("update Maps" +
" set mapName = ?," +
" mapDescription = ?," +
" mapSVG = ?," +
" mapLatitude = ?," +
" mapLongitude = ?," +
" mapAddress1 = ?," +
" mapAddress2 = ?," +
" mapCity = ?," +
" mapProvince = ?," +
" mapPostalCode = ?," +
" mapPhoneNumber = ?," +
" recordUpdate_userName = ?," +
" recordUpdate_timeMillis = ?" +
" where mapId = ?" +
" and recordDelete_timeMillis is null")
.run(mapForm.mapName, mapForm.mapDescription, mapForm.mapSVG, (mapForm.mapLatitude === "" ? undefined : mapForm.mapLatitude), (mapForm.mapLongitude === "" ? undefined : mapForm.mapLongitude), mapForm.mapAddress1, mapForm.mapAddress2, mapForm.mapCity, mapForm.mapProvince, mapForm.mapPostalCode, mapForm.mapPhoneNumber, requestSession.user.userName, rightNowMillis, mapForm.mapId);
database.close();
return result.changes > 0;
};
export default updateMap;

View File

@ -0,0 +1,68 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import type * as recordTypes from "../../types/recordTypes";
interface UpdateMapForm {
mapId: string;
mapName: string;
mapDescription: string;
mapSVG: string;
mapLatitude: string;
mapLongitude: string;
mapAddress1: string;
mapAddress2: string;
mapCity: string;
mapProvince: string;
mapPostalCode: string;
mapPhoneNumber: string;
}
export const updateMap =
(mapForm: UpdateMapForm, requestSession: recordTypes.PartialSession): boolean => {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const result = database
.prepare("update Maps" +
" set mapName = ?," +
" mapDescription = ?," +
" mapSVG = ?," +
" mapLatitude = ?," +
" mapLongitude = ?," +
" mapAddress1 = ?," +
" mapAddress2 = ?," +
" mapCity = ?," +
" mapProvince = ?," +
" mapPostalCode = ?," +
" mapPhoneNumber = ?," +
" recordUpdate_userName = ?," +
" recordUpdate_timeMillis = ?" +
" where mapId = ?" +
" and recordDelete_timeMillis is null")
.run(mapForm.mapName,
mapForm.mapDescription,
mapForm.mapSVG,
(mapForm.mapLatitude === "" ? undefined : mapForm.mapLatitude),
(mapForm.mapLongitude === "" ? undefined : mapForm.mapLongitude),
mapForm.mapAddress1,
mapForm.mapAddress2,
mapForm.mapCity,
mapForm.mapProvince,
mapForm.mapPostalCode,
mapForm.mapPhoneNumber,
requestSession.user.userName,
rightNowMillis,
mapForm.mapId);
database.close();
return result.changes > 0;
};
export default updateMap;

View File

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

View File

@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
const searchFilterFormElement = document.querySelector("#form--searchFilters");
const searchResultsContainerElement = document.querySelector("#container--searchResults");
const getLots = () => {
searchResultsContainerElement.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(urlPrefix + "/lots/doSearchLots", searchFilterFormElement, (responseJSON) => {
if (responseJSON.lots.length === 0) {
searchResultsContainerElement.innerHTML = "<div class=\"message is-info\">" +
"<p class=\"message-body\">There are no " + exports.aliases.lots.toLowerCase() + " that meet the search criteria.</p>" +
"</div>";
return;
}
const resultsTbodyElement = document.createElement("tbody");
for (const lot of responseJSON.lots) {
resultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" +
("<td>" +
"<a href=\"" + urlPrefix + "/lots/" + lot.lotId + "\">" +
lot.lotName +
"</a>" +
"</td>") +
"<td>" + lot.lotType + "</td>" +
"<td>" + lot.lotStatus + "</td>" +
"<td>" + lot.mapName + "</td>" +
"</tr>");
}
searchResultsContainerElement.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>";
searchResultsContainerElement.querySelector("table").append(resultsTbodyElement);
});
};
const filterElements = searchFilterFormElement.querySelectorAll("input, select");
for (const filterElement of filterElements) {
filterElement.addEventListener("change", getLots);
}
searchFilterFormElement.addEventListener("submit", (formEvent) => {
formEvent.preventDefault();
getLots();
});
getLots();
})();

View File

@ -0,0 +1,78 @@
/* eslint-disable unicorn/prefer-module */
import type * as recordTypes from "../types/recordTypes";
import type {
cityssmGlobal
} from "@cityssm/bulma-webapp-js/src/types";
declare const cityssm: cityssmGlobal;
(() => {
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
const searchFilterFormElement = document.querySelector("#form--searchFilters") as HTMLFormElement;
const searchResultsContainerElement = document.querySelector("#container--searchResults") as HTMLElement;
const getLots = () => {
searchResultsContainerElement.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(urlPrefix + "/lots/doSearchLots", searchFilterFormElement,
(responseJSON: {
lots: recordTypes.Lot[]
}) => {
if (responseJSON.lots.length === 0) {
searchResultsContainerElement.innerHTML = "<div class=\"message is-info\">" +
"<p class=\"message-body\">There are no " + exports.aliases.lots.toLowerCase() + " that meet the search criteria.</p>" +
"</div>";
return;
}
const resultsTbodyElement = document.createElement("tbody");
for (const lot of responseJSON.lots) {
resultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" +
("<td>" +
"<a href=\"" + urlPrefix + "/lots/" + lot.lotId + "\">" +
lot.lotName +
"</a>" +
"</td>") +
"<td>" + lot.lotType + "</td>" +
"<td>" + lot.lotStatus + "</td>" +
"<td>" + lot.mapName + "</td>" +
"</tr>");
}
searchResultsContainerElement.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>";
searchResultsContainerElement.querySelector("table").append(resultsTbodyElement);
});
};
const filterElements = searchFilterFormElement.querySelectorAll("input, select") as NodeListOf < HTMLInputElement | HTMLSelectElement > ;
for (const filterElement of filterElements) {
filterElement.addEventListener("change", getLots);
}
searchFilterFormElement.addEventListener("submit", (formEvent) => {
formEvent.preventDefault();
getLots();
});
getLots();
})();

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

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

View File

@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
const mapId = document.querySelector("#map--mapId").value;
const isCreate = (mapId === "");
const mapForm = document.querySelector("#form--map");
const updateMap = (formEvent) => {
formEvent.preventDefault();
cityssm.postJSON(urlPrefix + "/maps/" + (isCreate ? "doCreateMap" : "doUpdateMap"), mapForm, (responseJSON) => {
if (responseJSON.success) {
if (isCreate) {
window.location.href = urlPrefix + "/maps/" + responseJSON.mapId + "/edit";
}
else {
bulmaJS.alert({
message: exports.aliases.map + " Updated Successfully",
contextualColorName: "success"
});
}
}
else {
bulmaJS.alert({
title: "Error Updating " + exports.aliases.map,
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
});
};
mapForm.addEventListener("submit", updateMap);
})();

View File

@ -0,0 +1,45 @@
/* 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 mapId = (document.querySelector("#map--mapId") as HTMLInputElement).value;
const isCreate = (mapId === "");
const mapForm = document.querySelector("#form--map") as HTMLFormElement;
const updateMap = (formEvent: SubmitEvent) => {
formEvent.preventDefault();
cityssm.postJSON(urlPrefix + "/maps/" + (isCreate ? "doCreateMap" : "doUpdateMap"),
mapForm,
(responseJSON: { success: boolean; mapId?: number, errorMessage?: string}) => {
if (responseJSON.success) {
if (isCreate) {
window.location.href = urlPrefix + "/maps/" + responseJSON.mapId + "/edit";
} else {
bulmaJS.alert({
message: exports.aliases.map + " Updated Successfully",
contextualColorName: "success"
});
}
} else {
bulmaJS.alert({
title: "Error Updating " + exports.aliases.map,
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
});
};
mapForm.addEventListener("submit", updateMap);
})();

View File

@ -29,9 +29,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
continue; continue;
} }
searchResultCount += 1; searchResultCount += 1;
const mapName = map.mapName === "" const mapName = map.mapName === "" ?
? "(No Name)" "(No Name)" :
: map.mapName; map.mapName;
searchResultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" + searchResultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" +
("<td>" + ("<td>" +
"<a class=\"has-text-weight-bold\" href=\"" + urlPrefix + "/maps/" + map.mapId + "\">" + "<a class=\"has-text-weight-bold\" href=\"" + urlPrefix + "/maps/" + map.mapId + "\">" +
@ -40,16 +40,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
cityssm.escapeHTML(map.mapAddress1) + cityssm.escapeHTML(map.mapAddress1) +
"</td>") + "</td>") +
"<td class=\"has-text-centered\">" + "<td class=\"has-text-centered\">" +
(map.mapLatitude && map.mapLongitude (map.mapLatitude && map.mapLongitude ?
? "<i class=\"fas fa-map-marker-alt\" title=\"Has Geographic Coordinates\"></i>" "<i class=\"fas fa-map-marker-alt\" title=\"Has Geographic Coordinates\"></i>" :
: "") + "") +
"</td>" + "</td>" +
"<td class=\"has-text-centered\">" + "<td class=\"has-text-centered\">" +
(map.mapSVG (map.mapSVG ?
? "<i class=\"fas fa-image\" title=\"Has Image\"></i>" "<i class=\"fas fa-image\" title=\"Has Image\"></i>" :
: "") + "") +
"</td>" + "</td>" +
"<td class=\"has-text-right\">" + map.lotCount + "</td>" + ("<td class=\"has-text-right\">" +
"<a href=\"" + urlPrefix + "/lots?mapId=" + map.mapId + "\">" +
map.lotCount +
"</a>" +
"</td>") +
"</tr>"); "</tr>");
} }
searchResultsContainerElement.innerHTML = ""; searchResultsContainerElement.innerHTML = "";
@ -72,6 +76,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
}; };
searchFilterElement.addEventListener("keyup", renderResults); searchFilterElement.addEventListener("keyup", renderResults);
document.querySelector("#form--searchFilters").addEventListener("submit", renderResults); document.querySelector("#form--searchFilters").addEventListener("submit", (formEvent) => {
formEvent.preventDefault();
renderResults();
});
renderResults(); renderResults();
})(); })();

View File

@ -2,11 +2,12 @@
import type * as recordTypes from "../types/recordTypes"; import type * as recordTypes from "../types/recordTypes";
import type { cityssmGlobal } from "@cityssm/bulma-webapp-js/src/types"; import type {
import type { BulmaJS } from "@cityssm/bulma-js/types"; cityssmGlobal
} from "@cityssm/bulma-webapp-js/src/types";
declare const cityssm: cityssmGlobal; declare const cityssm: cityssmGlobal;
declare const bulmaJS: BulmaJS;
(() => { (() => {
const urlPrefix = document.querySelector("main").dataset.urlPrefix; const urlPrefix = document.querySelector("main").dataset.urlPrefix;
@ -50,9 +51,9 @@ declare const bulmaJS: BulmaJS;
searchResultCount += 1; searchResultCount += 1;
const mapName = map.mapName === "" const mapName = map.mapName === "" ?
? "(No Name)" "(No Name)" :
: map.mapName; map.mapName;
searchResultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" + searchResultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" +
("<td>" + ("<td>" +
@ -62,16 +63,20 @@ declare const bulmaJS: BulmaJS;
cityssm.escapeHTML(map.mapAddress1) + cityssm.escapeHTML(map.mapAddress1) +
"</td>") + "</td>") +
"<td class=\"has-text-centered\">" + "<td class=\"has-text-centered\">" +
(map.mapLatitude && map.mapLongitude (map.mapLatitude && map.mapLongitude ?
? "<i class=\"fas fa-map-marker-alt\" title=\"Has Geographic Coordinates\"></i>" "<i class=\"fas fa-map-marker-alt\" title=\"Has Geographic Coordinates\"></i>" :
: "") + "") +
"</td>" + "</td>" +
"<td class=\"has-text-centered\">" + "<td class=\"has-text-centered\">" +
(map.mapSVG (map.mapSVG ?
? "<i class=\"fas fa-image\" title=\"Has Image\"></i>" "<i class=\"fas fa-image\" title=\"Has Image\"></i>" :
: "") + "") +
"</td>" + "</td>" +
"<td class=\"has-text-right\">" + map.lotCount + "</td>" + ("<td class=\"has-text-right\">" +
"<a href=\"" + urlPrefix + "/lots?mapId=" + map.mapId + "\">" +
map.lotCount +
"</a>" +
"</td>") +
"</tr>"); "</tr>");
} }
@ -101,7 +106,10 @@ declare const bulmaJS: BulmaJS;
}; };
searchFilterElement.addEventListener("keyup", renderResults); searchFilterElement.addEventListener("keyup", renderResults);
document.querySelector("#form--searchFilters").addEventListener("submit", renderResults); document.querySelector("#form--searchFilters").addEventListener("submit", (formEvent) => {
formEvent.preventDefault();
renderResults();
});
renderResults(); renderResults();
})(); })();

View File

Before

Width:  |  Height:  |  Size: 384 KiB

After

Width:  |  Height:  |  Size: 384 KiB

View File

Before

Width:  |  Height:  |  Size: 239 KiB

After

Width:  |  Height:  |  Size: 239 KiB

Some files were not shown because too many files have changed in this diff Show More