- lot summaries on map edit
- link to create lot from map edit
- more info on map search
- include lots and occupant on work order search
- include map name where work orders are shown
- more work order search filters
- add cogs to admin dashboard icons
- fix read only bug getting fee categories
deepsource-autofix-76c6eb20
Dan Gowans 2022-09-30 15:47:20 -04:00
parent 12397aa4aa
commit 5ad8e76760
29 changed files with 529 additions and 109 deletions

View File

@ -1,11 +1,21 @@
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 * as cacheFunctions from "../../helpers/functions.cache.js"; import * as cacheFunctions from "../../helpers/functions.cache.js";
export const handler = (_request, response) => { export const handler = (request, response) => {
const lot = { const lot = {
lotOccupancies: [] lotOccupancies: []
}; };
const maps = getMaps(); const maps = getMaps();
if (request.query.mapId) {
const mapId = Number.parseInt(request.query.mapId, 10);
const map = maps.find((possibleMap) => {
return mapId === possibleMap.mapId;
});
if (map) {
lot.mapId = map.mapId;
lot.mapName = map.mapName;
}
}
const lotTypes = cacheFunctions.getLotTypes(); const lotTypes = cacheFunctions.getLotTypes();
const lotStatuses = cacheFunctions.getLotStatuses(); const lotStatuses = cacheFunctions.getLotStatuses();
response.render("lot-edit", { response.render("lot-edit", {

View File

@ -7,12 +7,26 @@ import * as cacheFunctions from "../../helpers/functions.cache.js";
import * as recordTypes from "../../types/recordTypes"; import * as recordTypes from "../../types/recordTypes";
export const handler: RequestHandler = (_request, response) => { export const handler: RequestHandler = (request, response) => {
const lot: recordTypes.Lot = { const lot: recordTypes.Lot = {
lotOccupancies: [] lotOccupancies: []
}; };
const maps = getMaps(); const maps = getMaps();
if (request.query.mapId) {
const mapId = Number.parseInt(request.query.mapId as string, 10);
const map = maps.find((possibleMap) => {
return mapId === possibleMap.mapId;
});
if (map) {
lot.mapId = map.mapId;
lot.mapName = map.mapName;
}
}
const lotTypes = cacheFunctions.getLotTypes(); const lotTypes = cacheFunctions.getLotTypes();
const lotStatuses = cacheFunctions.getLotStatuses(); const lotStatuses = cacheFunctions.getLotStatuses();

View File

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

View File

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

View File

@ -2,7 +2,8 @@ import { getWorkOrders } from "../../helpers/lotOccupancyDB/getWorkOrders.js";
export const handler = async (request, response) => { export const handler = async (request, response) => {
const result = getWorkOrders(request.body, { const result = getWorkOrders(request.body, {
limit: request.body.limit, limit: request.body.limit,
offset: request.body.offset offset: request.body.offset,
includeLotsAndLotOccupancies: true
}); });
response.json({ response.json({
count: result.count, count: result.count,

View File

@ -5,7 +5,8 @@ import { getWorkOrders } from "../../helpers/lotOccupancyDB/getWorkOrders.js";
export const handler: RequestHandler = async (request, response) => { export const handler: RequestHandler = async (request, response) => {
const result = getWorkOrders(request.body, { const result = getWorkOrders(request.body, {
limit: request.body.limit, limit: request.body.limit,
offset: request.body.offset offset: request.body.offset,
includeLotsAndLotOccupancies: true
}); });
response.json({ response.json({

View File

@ -32,7 +32,7 @@ export const getFeeCategories = (filters, options) => {
let expectedFeeCategoryOrderNumber = -1; let expectedFeeCategoryOrderNumber = -1;
for (const feeCategory of feeCategories) { for (const feeCategory of feeCategories) {
expectedFeeCategoryOrderNumber += 1; expectedFeeCategoryOrderNumber += 1;
if (feeCategory.orderNumber !== expectedFeeCategoryOrderNumber) { if (updateOrderNumbers && feeCategory.orderNumber !== expectedFeeCategoryOrderNumber) {
database database
.prepare("update FeeCategories" + .prepare("update FeeCategories" +
" set orderNumber = ?" + " set orderNumber = ?" +

View File

@ -61,7 +61,7 @@ export const getFeeCategories = (
for (const feeCategory of feeCategories) { for (const feeCategory of feeCategories) {
expectedFeeCategoryOrderNumber += 1; expectedFeeCategoryOrderNumber += 1;
if (feeCategory.orderNumber !== expectedFeeCategoryOrderNumber) { if (updateOrderNumbers && feeCategory.orderNumber !== expectedFeeCategoryOrderNumber) {
database database
.prepare( .prepare(
"update FeeCategories" + "update FeeCategories" +

View File

@ -3,10 +3,15 @@ interface GetWorkOrdersFilters {
workOrderTypeId?: number | string; workOrderTypeId?: number | string;
workOrderOpenStatus?: "" | "open" | "closed"; workOrderOpenStatus?: "" | "open" | "closed";
workOrderOpenDateString?: string; workOrderOpenDateString?: string;
occupantName?: string;
lotName?: string;
} }
interface GetWorkOrdersOptions { interface GetWorkOrdersOptions {
limit: number; limit: number;
offset: number; offset: number;
includeLotsAndLotOccupancies?: boolean;
includeComments?: boolean;
includeMilestones?: boolean;
} }
export declare const getWorkOrders: (filters?: GetWorkOrdersFilters, options?: GetWorkOrdersOptions) => { export declare const getWorkOrders: (filters?: GetWorkOrdersFilters, options?: GetWorkOrdersOptions) => {
count: number; count: number;

View File

@ -1,6 +1,10 @@
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 { dateIntegerToString, dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import { dateIntegerToString, dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
import { getWorkOrderComments } from "./getWorkOrderComments.js";
import { getLots } from "./getLots.js";
import { getLotOccupancies } from "./getLotOccupancies.js";
import { getWorkOrderMilestones } from "./getWorkOrderMilestones.js";
export const getWorkOrders = (filters, options) => { export const getWorkOrders = (filters, options) => {
const database = sqlite(databasePath, { const database = sqlite(databasePath, {
readonly: true readonly: true
@ -24,10 +28,26 @@ export const getWorkOrders = (filters, options) => {
sqlWhereClause += " and w.workOrderOpenDate = ?"; sqlWhereClause += " and w.workOrderOpenDate = ?";
sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString)); sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString));
} }
if (filters.occupantName) {
const occupantNamePieces = filters.occupantName.toLowerCase().split(" ");
for (const occupantNamePiece of occupantNamePieces) {
sqlWhereClause +=
" and w.workOrderId in (" +
"select workOrderId from WorkOrderLotOccupancies where recordDelete_timeMillis is null and lotOccupancyId in (select lotOccupancyId from LotOccupancyOccupants where recordDelete_timeMillis is null and instr(lower(occupantName), ?)))";
sqlParameters.push(occupantNamePiece);
}
}
if (filters.lotName) {
const lotNamePieces = filters.lotName.toLowerCase().split(" ");
for (const lotNamePiece of lotNamePieces) {
sqlWhereClause +=
" and w.workOrderId in (" +
"select workOrderId from WorkOrderLots where recordDelete_timeMillis is null and lotId in (select lotId from Lots oo where recordDelete_timeMillis is null and instr(lower(lotName), ?)))";
sqlParameters.push(lotNamePiece);
}
}
const count = database const count = database
.prepare("select count(*) as recordCount" + .prepare("select count(*) as recordCount" + " from WorkOrders w" + sqlWhereClause)
" from WorkOrders w" +
sqlWhereClause)
.get(sqlParameters).recordCount; .get(sqlParameters).recordCount;
let workOrders = []; let workOrders = [];
if (count > 0) { if (count > 0) {
@ -49,14 +69,40 @@ export const getWorkOrders = (filters, options) => {
" group by workOrderId) m on w.workOrderId = m.workOrderId") + " group by workOrderId) m on w.workOrderId = m.workOrderId") +
sqlWhereClause + sqlWhereClause +
" order by w.workOrderOpenDate desc, w.workOrderNumber" + " order by w.workOrderOpenDate desc, w.workOrderNumber" +
(options (options ? " limit " + options.limit + " offset " + options.offset : ""))
? " limit " +
options.limit +
" offset " +
options.offset
: ""))
.all(sqlParameters); .all(sqlParameters);
} }
if (options.includeComments ||
options.includeLotsAndLotOccupancies ||
options.includeMilestones) {
for (const workOrder of workOrders) {
if (options.includeComments) {
workOrder.workOrderComments = getWorkOrderComments(workOrder.workOrderId, database);
}
if (options.includeLotsAndLotOccupancies) {
workOrder.workOrderLots = getLots({
workOrderId: workOrder.workOrderId
}, {
limit: -1,
offset: 0
}, database).lots;
workOrder.workOrderLotOccupancies = getLotOccupancies({
workOrderId: workOrder.workOrderId
}, {
limit: -1,
offset: 0,
includeOccupants: true
}, database).lotOccupancies;
}
if (options.includeMilestones) {
workOrder.workOrderMilestones = getWorkOrderMilestones({
workOrderId: workOrder.workOrderId
}, {
orderBy: "date"
}, database);
}
}
}
database.close(); database.close();
return { return {
count, count,

View File

@ -2,7 +2,15 @@ import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js"; import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import { dateIntegerToString, dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js"; import {
dateIntegerToString,
dateStringToInteger
} from "@cityssm/expressjs-server-js/dateTimeFns.js";
import { getWorkOrderComments } from "./getWorkOrderComments.js";
import { getLots } from "./getLots.js";
import { getLotOccupancies } from "./getLotOccupancies.js";
import { getWorkOrderMilestones } from "./getWorkOrderMilestones.js";
import type * as recordTypes from "../../types/recordTypes"; import type * as recordTypes from "../../types/recordTypes";
@ -10,11 +18,16 @@ interface GetWorkOrdersFilters {
workOrderTypeId?: number | string; workOrderTypeId?: number | string;
workOrderOpenStatus?: "" | "open" | "closed"; workOrderOpenStatus?: "" | "open" | "closed";
workOrderOpenDateString?: string; workOrderOpenDateString?: string;
occupantName?: string;
lotName?: string;
} }
interface GetWorkOrdersOptions { interface GetWorkOrdersOptions {
limit: number; limit: number;
offset: number; offset: number;
includeLotsAndLotOccupancies?: boolean;
includeComments?: boolean;
includeMilestones?: boolean;
} }
export const getWorkOrders = ( export const getWorkOrders = (
@ -51,12 +64,28 @@ export const getWorkOrders = (
sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString)); sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString));
} }
if (filters.occupantName) {
const occupantNamePieces = filters.occupantName.toLowerCase().split(" ");
for (const occupantNamePiece of occupantNamePieces) {
sqlWhereClause +=
" and w.workOrderId in (" +
"select workOrderId from WorkOrderLotOccupancies where recordDelete_timeMillis is null and lotOccupancyId in (select lotOccupancyId from LotOccupancyOccupants where recordDelete_timeMillis is null and instr(lower(occupantName), ?)))";
sqlParameters.push(occupantNamePiece);
}
}
if (filters.lotName) {
const lotNamePieces = filters.lotName.toLowerCase().split(" ");
for (const lotNamePiece of lotNamePieces) {
sqlWhereClause +=
" and w.workOrderId in (" +
"select workOrderId from WorkOrderLots where recordDelete_timeMillis is null and lotId in (select lotId from Lots oo where recordDelete_timeMillis is null and instr(lower(lotName), ?)))";
sqlParameters.push(lotNamePiece);
}
}
const count: number = database const count: number = database
.prepare( .prepare("select count(*) as recordCount" + " from WorkOrders w" + sqlWhereClause)
"select count(*) as recordCount" +
" from WorkOrders w" +
sqlWhereClause
)
.get(sqlParameters).recordCount; .get(sqlParameters).recordCount;
let workOrders: recordTypes.WorkOrder[] = []; let workOrders: recordTypes.WorkOrder[] = [];
@ -81,16 +110,60 @@ export const getWorkOrders = (
" group by workOrderId) m on w.workOrderId = m.workOrderId") + " group by workOrderId) m on w.workOrderId = m.workOrderId") +
sqlWhereClause + sqlWhereClause +
" order by w.workOrderOpenDate desc, w.workOrderNumber" + " order by w.workOrderOpenDate desc, w.workOrderNumber" +
(options (options ? " limit " + options.limit + " offset " + options.offset : "")
? " limit " +
options.limit +
" offset " +
options.offset
: "")
) )
.all(sqlParameters); .all(sqlParameters);
} }
if (
options.includeComments ||
options.includeLotsAndLotOccupancies ||
options.includeMilestones
) {
for (const workOrder of workOrders) {
if (options.includeComments) {
workOrder.workOrderComments = getWorkOrderComments(workOrder.workOrderId, database);
}
if (options.includeLotsAndLotOccupancies) {
workOrder.workOrderLots = getLots(
{
workOrderId: workOrder.workOrderId
},
{
limit: -1,
offset: 0
},
database
).lots;
workOrder.workOrderLotOccupancies = getLotOccupancies(
{
workOrderId: workOrder.workOrderId
},
{
limit: -1,
offset: 0,
includeOccupants: true
},
database
).lotOccupancies;
}
if (options.includeMilestones) {
workOrder.workOrderMilestones = getWorkOrderMilestones(
{
workOrderId: workOrder.workOrderId
},
{
orderBy: "date"
},
database
);
}
}
}
database.close(); database.close();
return { return {

13
package-lock.json generated
View File

@ -41,6 +41,7 @@
"@cityssm/bulma-a11y": "^0.4.0", "@cityssm/bulma-a11y": "^0.4.0",
"@cityssm/bulma-sticky-table": "^2.0.1", "@cityssm/bulma-sticky-table": "^2.0.1",
"@cityssm/bulma-webapp-css": "^0.12.0", "@cityssm/bulma-webapp-css": "^0.12.0",
"@cityssm/fa-glow": "^0.1.0",
"@cityssm/mssql-multi-pool": "^2.1.6", "@cityssm/mssql-multi-pool": "^2.1.6",
"@cityssm/simple-fa5-checkbox": "^0.2.1", "@cityssm/simple-fa5-checkbox": "^0.2.1",
"@types/activedirectory2": "^1.2.3", "@types/activedirectory2": "^1.2.3",
@ -590,6 +591,12 @@
"node": "^12.20.0 || ^14.13.1 || >=16.0.0" "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
} }
}, },
"node_modules/@cityssm/fa-glow": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@cityssm/fa-glow/-/fa-glow-0.1.0.tgz",
"integrity": "sha512-lHddtgbHA26+xgKBBgVQl6japGah2M+L+5z+lRuEV/P76DBSI2fifuCukUhX6k7Rvbiw+qkDSPPxwKJGggr+BA==",
"dev": true
},
"node_modules/@cityssm/mssql-multi-pool": { "node_modules/@cityssm/mssql-multi-pool": {
"version": "2.1.6", "version": "2.1.6",
"resolved": "https://registry.npmjs.org/@cityssm/mssql-multi-pool/-/mssql-multi-pool-2.1.6.tgz", "resolved": "https://registry.npmjs.org/@cityssm/mssql-multi-pool/-/mssql-multi-pool-2.1.6.tgz",
@ -12609,6 +12616,12 @@
"libphonenumber-js": "^1.10.13" "libphonenumber-js": "^1.10.13"
} }
}, },
"@cityssm/fa-glow": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@cityssm/fa-glow/-/fa-glow-0.1.0.tgz",
"integrity": "sha512-lHddtgbHA26+xgKBBgVQl6japGah2M+L+5z+lRuEV/P76DBSI2fifuCukUhX6k7Rvbiw+qkDSPPxwKJGggr+BA==",
"dev": true
},
"@cityssm/mssql-multi-pool": { "@cityssm/mssql-multi-pool": {
"version": "2.1.6", "version": "2.1.6",
"resolved": "https://registry.npmjs.org/@cityssm/mssql-multi-pool/-/mssql-multi-pool-2.1.6.tgz", "resolved": "https://registry.npmjs.org/@cityssm/mssql-multi-pool/-/mssql-multi-pool-2.1.6.tgz",

View File

@ -65,6 +65,7 @@
"@cityssm/bulma-a11y": "^0.4.0", "@cityssm/bulma-a11y": "^0.4.0",
"@cityssm/bulma-sticky-table": "^2.0.1", "@cityssm/bulma-sticky-table": "^2.0.1",
"@cityssm/bulma-webapp-css": "^0.12.0", "@cityssm/bulma-webapp-css": "^0.12.0",
"@cityssm/fa-glow": "^0.1.0",
"@cityssm/mssql-multi-pool": "^2.1.6", "@cityssm/mssql-multi-pool": "^2.1.6",
"@cityssm/simple-fa5-checkbox": "^0.2.1", "@cityssm/simple-fa5-checkbox": "^0.2.1",
"@types/activedirectory2": "^1.2.3", "@types/activedirectory2": "^1.2.3",

View File

@ -1,6 +1,7 @@
@import "@cityssm/bulma-webapp-css/cityssm"; @import "@cityssm/bulma-webapp-css/cityssm";
@import "bulma/sass/utilities/derived-variables"; @import "bulma/sass/utilities/derived-variables";
@import "bulma-calendar/src/sass/index"; @import "bulma-calendar/src/sass/index";
@import "@cityssm/fa-glow/fa-glow";
$white: #fff; $white: #fff;
$black: #000; $black: #000;

View File

@ -9,16 +9,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
searchResultsContainerElement.innerHTML = searchResultsContainerElement.innerHTML =
'<div class="has-text-grey has-text-centered">' + '<div class="has-text-grey has-text-centered">' +
'<i class="fas fa-5x fa-circle-notch fa-spin" aria-hidden="true"></i><br />' + '<i class="fas fa-5x fa-circle-notch fa-spin" aria-hidden="true"></i><br />' +
"Loading " + ("Loading " + exports.aliases.maps + "...") +
exports.aliases.maps +
"..." +
"</div>"; "</div>";
let searchResultCount = 0; let searchResultCount = 0;
const searchResultsTbodyElement = document.createElement("tbody"); const searchResultsTbodyElement = document.createElement("tbody");
const filterStringSplit = searchFilterElement.value const filterStringSplit = searchFilterElement.value.trim().toLowerCase().split(" ");
.trim()
.toLowerCase()
.split(" ");
for (const map of maps) { for (const map of maps) {
const mapSearchString = (map.mapName + const mapSearchString = (map.mapName +
" " + " " +
@ -47,16 +42,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
'">' + '">' +
cityssm.escapeHTML(map.mapName || "(No Name)") + cityssm.escapeHTML(map.mapName || "(No Name)") +
"</a><br />" + "</a><br />" +
cityssm.escapeHTML(map.mapAddress1) + '<span class="is-size-7">' +
cityssm.escapeHTML(map.mapDescription) +
"</span>" +
"</td>") + "</td>") +
("<td>" +
(map.mapAddress1 ? cityssm.escapeHTML(map.mapAddress1) + "<br />" : "") +
(map.mapAddress2 ? cityssm.escapeHTML(map.mapAddress2) + "<br />" : "") +
(map.mapCity || map.mapProvince
? cityssm.escapeHTML(map.mapCity) +
", " +
cityssm.escapeHTML(map.mapProvince) +
"<br />"
: "") +
(map.mapPostalCode ? cityssm.escapeHTML(map.mapPostalCode) : "") +
"</td>") +
("<td>" + cityssm.escapeHTML(map.mapPhoneNumber) + "</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>' ? '<span data-tooltip="Has Geographic Coordinates"><i class="fas fa-map-marker-alt" aria-label="Has Geographic Coordinates"></i></span>'
: "") + : "") +
"</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>' ? '<span data-tooltip="Has Image"><i class="fas fa-image" aria-label="Has Image"></i></span>'
: "") + : "") +
"</td>" + "</td>" +
('<td class="has-text-right">' + ('<td class="has-text-right">' +
@ -85,23 +94,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
"table is-fullwidth is-striped is-hoverable has-sticky-header"; "table is-fullwidth is-striped is-hoverable has-sticky-header";
searchResultsTableElement.innerHTML = searchResultsTableElement.innerHTML =
"<thead><tr>" + "<thead><tr>" +
"<th>" + ("<th>" + exports.aliases.map + "</th>") +
exports.aliases.map + "<th>Address</th>" +
"</th>" + "<th>Phone Number</th>" +
'<th class="has-text-centered">Coordinates</th>' + '<th class="has-text-centered">Coordinates</th>' +
'<th class="has-text-centered">Image</th>' + '<th class="has-text-centered">Image</th>' +
'<th class="has-text-right">' + ('<th class="has-text-right">' + exports.aliases.lot + " Count</th>") +
exports.aliases.lot +
" Count</th>" +
"</tr></thead>"; "</tr></thead>";
searchResultsTableElement.append(searchResultsTbodyElement); searchResultsTableElement.append(searchResultsTbodyElement);
searchResultsContainerElement.append(searchResultsTableElement); searchResultsContainerElement.append(searchResultsTableElement);
} }
}; };
searchFilterElement.addEventListener("keyup", renderResults); searchFilterElement.addEventListener("keyup", renderResults);
document document.querySelector("#form--searchFilters").addEventListener("submit", (formEvent) => {
.querySelector("#form--searchFilters")
.addEventListener("submit", (formEvent) => {
formEvent.preventDefault(); formEvent.preventDefault();
renderResults(); renderResults();
}); });

View File

@ -11,9 +11,7 @@ declare const cityssm: cityssmGlobal;
const maps: recordTypes.Map[] = exports.maps; const maps: recordTypes.Map[] = exports.maps;
const searchFilterElement = document.querySelector( const searchFilterElement = document.querySelector("#searchFilter--map") as HTMLInputElement;
"#searchFilter--map"
) as HTMLInputElement;
const searchResultsContainerElement = document.querySelector( const searchResultsContainerElement = document.querySelector(
"#container--searchResults" "#container--searchResults"
@ -23,18 +21,13 @@ declare const cityssm: cityssmGlobal;
searchResultsContainerElement.innerHTML = searchResultsContainerElement.innerHTML =
'<div class="has-text-grey has-text-centered">' + '<div class="has-text-grey has-text-centered">' +
'<i class="fas fa-5x fa-circle-notch fa-spin" aria-hidden="true"></i><br />' + '<i class="fas fa-5x fa-circle-notch fa-spin" aria-hidden="true"></i><br />' +
"Loading " + ("Loading " + exports.aliases.maps + "...") +
exports.aliases.maps +
"..." +
"</div>"; "</div>";
let searchResultCount = 0; let searchResultCount = 0;
const searchResultsTbodyElement = document.createElement("tbody"); const searchResultsTbodyElement = document.createElement("tbody");
const filterStringSplit = searchFilterElement.value const filterStringSplit = searchFilterElement.value.trim().toLowerCase().split(" ");
.trim()
.toLowerCase()
.split(" ");
for (const map of maps) { for (const map of maps) {
const mapSearchString = ( const mapSearchString = (
@ -73,16 +66,30 @@ declare const cityssm: cityssmGlobal;
'">' + '">' +
cityssm.escapeHTML(map.mapName || "(No Name)") + cityssm.escapeHTML(map.mapName || "(No Name)") +
"</a><br />" + "</a><br />" +
cityssm.escapeHTML(map.mapAddress1) + '<span class="is-size-7">' +
cityssm.escapeHTML(map.mapDescription) +
"</span>" +
"</td>") + "</td>") +
("<td>" +
(map.mapAddress1 ? cityssm.escapeHTML(map.mapAddress1) + "<br />" : "") +
(map.mapAddress2 ? cityssm.escapeHTML(map.mapAddress2) + "<br />" : "") +
(map.mapCity || map.mapProvince
? cityssm.escapeHTML(map.mapCity) +
", " +
cityssm.escapeHTML(map.mapProvince) +
"<br />"
: "") +
(map.mapPostalCode ? cityssm.escapeHTML(map.mapPostalCode) : "") +
"</td>") +
("<td>" + cityssm.escapeHTML(map.mapPhoneNumber) + "</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>' ? '<span data-tooltip="Has Geographic Coordinates"><i class="fas fa-map-marker-alt" aria-label="Has Geographic Coordinates"></i></span>'
: "") + : "") +
"</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>' ? '<span data-tooltip="Has Image"><i class="fas fa-image" aria-label="Has Image"></i></span>'
: "") + : "") +
"</td>" + "</td>" +
('<td class="has-text-right">' + ('<td class="has-text-right">' +
@ -109,18 +116,18 @@ declare const cityssm: cityssmGlobal;
"</div>"; "</div>";
} else { } else {
const searchResultsTableElement = document.createElement("table"); const searchResultsTableElement = document.createElement("table");
searchResultsTableElement.className = searchResultsTableElement.className =
"table is-fullwidth is-striped is-hoverable has-sticky-header"; "table is-fullwidth is-striped is-hoverable has-sticky-header";
searchResultsTableElement.innerHTML = searchResultsTableElement.innerHTML =
"<thead><tr>" + "<thead><tr>" +
"<th>" + ("<th>" + exports.aliases.map + "</th>") +
exports.aliases.map + "<th>Address</th>" +
"</th>" + "<th>Phone Number</th>" +
'<th class="has-text-centered">Coordinates</th>' + '<th class="has-text-centered">Coordinates</th>' +
'<th class="has-text-centered">Image</th>' + '<th class="has-text-centered">Image</th>' +
'<th class="has-text-right">' + ('<th class="has-text-right">' + exports.aliases.lot + " Count</th>") +
exports.aliases.lot +
" Count</th>" +
"</tr></thead>"; "</tr></thead>";
searchResultsTableElement.append(searchResultsTbodyElement); searchResultsTableElement.append(searchResultsTbodyElement);
@ -130,9 +137,8 @@ declare const cityssm: cityssmGlobal;
}; };
searchFilterElement.addEventListener("keyup", renderResults); searchFilterElement.addEventListener("keyup", renderResults);
document
.querySelector("#form--searchFilters") document.querySelector("#form--searchFilters").addEventListener("submit", (formEvent) => {
.addEventListener("submit", (formEvent) => {
formEvent.preventDefault(); formEvent.preventDefault();
renderResults(); renderResults();
}); });

View File

@ -39,10 +39,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
let lotOccupancyHTML = ""; let lotOccupancyHTML = "";
for (const lot of milestone.workOrderLots) { for (const lot of milestone.workOrderLots) {
lotOccupancyHTML += lotOccupancyHTML +=
'<span class="has-tooltip-left" data-tooltip="' +
cityssm.escapeHTML(lot.mapName) +
'">' +
'<i class="fas fa-vector-square" aria-label="' + '<i class="fas fa-vector-square" aria-label="' +
cityssm.escapeHTML(exports.aliases.lot) + cityssm.escapeHTML(exports.aliases.lot) +
'"></i> ' + '"></i> ' +
cityssm.escapeHTML(lot.lotName) + cityssm.escapeHTML(lot.lotName) +
"</span>" +
"<br />"; "<br />";
} }
for (const lotOccupancy of milestone.workOrderLotOccupancies) { for (const lotOccupancy of milestone.workOrderLotOccupancies) {

View File

@ -73,10 +73,14 @@ declare const cityssm: cityssmGlobal;
for (const lot of milestone.workOrderLots) { for (const lot of milestone.workOrderLots) {
lotOccupancyHTML += lotOccupancyHTML +=
'<span class="has-tooltip-left" data-tooltip="' +
cityssm.escapeHTML(lot.mapName) +
'">' +
'<i class="fas fa-vector-square" aria-label="' + '<i class="fas fa-vector-square" aria-label="' +
cityssm.escapeHTML(exports.aliases.lot) + cityssm.escapeHTML(exports.aliases.lot) +
'"></i> ' + '"></i> ' +
cityssm.escapeHTML(lot.lotName) + cityssm.escapeHTML(lot.lotName) +
"</span>" +
"<br />"; "<br />";
} }

View File

@ -26,6 +26,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
} }
const resultsTbodyElement = document.createElement("tbody"); const resultsTbodyElement = document.createElement("tbody");
for (const workOrder of responseJSON.workOrders) { for (const workOrder of responseJSON.workOrders) {
let relatedHTML = "";
for (const lot of workOrder.workOrderLots) {
relatedHTML +=
'<span class="has-tooltip-left" data-tooltip="' +
cityssm.escapeHTML(lot.mapName) +
'">' +
'<i class="fas fa-vector-square" aria-label="' +
cityssm.escapeHTML(exports.aliases.lot) +
'"></i> ' +
cityssm.escapeHTML(lot.lotName || "(No Lot Name)") +
"</span><br />";
}
for (const occupancy of workOrder.workOrderLotOccupancies) {
for (const occupant of occupancy.lotOccupancyOccupants) {
relatedHTML +=
'<span class="has-tooltip-left" data-tooltip="' +
cityssm.escapeHTML(occupant.lotOccupantType) +
'">' +
'<i class="fas fa-user" aria-label="' +
cityssm.escapeHTML(exports.aliases.occupant) +
'"></i> ' +
cityssm.escapeHTML(occupant.occupantName || "(No Name)") +
"</span><br />";
}
}
resultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" + resultsTbodyElement.insertAdjacentHTML("beforeend", "<tr>" +
("<td>" + ("<td>" +
'<a class="has-text-weight-bold" href="' + '<a class="has-text-weight-bold" href="' +
@ -45,12 +70,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
cityssm.escapeHTML(workOrder.workOrderDescription) + cityssm.escapeHTML(workOrder.workOrderDescription) +
"</span>" + "</span>" +
"</td>") + "</td>") +
('<td class="is-nowrap"><span class="is-size-7">' +
relatedHTML +
"</span></td>") +
('<td class="is-nowrap">' + ('<td class="is-nowrap">' +
('<span data-tooltip="Open Date">' + ('<span class="has-tooltip-left" data-tooltip="Open Date">' +
'<i class="fas fa-fw fa-play" aria-label="Open Date"></i> ' + '<i class="fas fa-fw fa-play" aria-label="Open Date"></i> ' +
workOrder.workOrderOpenDateString + workOrder.workOrderOpenDateString +
"</span><br />") + "</span><br />") +
('<span data-tooltip="Close Date">' + ('<span class="has-tooltip-left" data-tooltip="Close Date">' +
'<i class="fas fa-fw fa-stop" aria-label="Close Date"></i> ' + '<i class="fas fa-fw fa-stop" aria-label="Close Date"></i> ' +
(workOrder.workOrderCloseDate (workOrder.workOrderCloseDate
? workOrder.workOrderCloseDateString ? workOrder.workOrderCloseDateString
@ -83,7 +111,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
'<table class="table is-fullwidth is-striped is-hoverable has-sticky-header">' + '<table class="table is-fullwidth is-striped is-hoverable has-sticky-header">' +
"<thead><tr>" + "<thead><tr>" +
"<th>Work Order Number</th>" + "<th>Work Order Number</th>" +
"<th>Work Order Description</th>" + "<th>Description</th>" +
"<th>Related</th>" +
"<th>Date</th>" + "<th>Date</th>" +
'<th class="has-tooltip-bottom" data-tooltip="Completed / Total Milestones">Progress</th>' + '<th class="has-tooltip-bottom" data-tooltip="Completed / Total Milestones">Progress</th>' +
(workOrderPrints.length > 0 ? '<th class="has-width-1"></th>' : "") + (workOrderPrints.length > 0 ? '<th class="has-width-1"></th>' : "") +

View File

@ -55,6 +55,34 @@ declare const cityssm: cityssmGlobal;
const resultsTbodyElement = document.createElement("tbody"); const resultsTbodyElement = document.createElement("tbody");
for (const workOrder of responseJSON.workOrders) { for (const workOrder of responseJSON.workOrders) {
let relatedHTML = "";
for (const lot of workOrder.workOrderLots) {
relatedHTML +=
'<span class="has-tooltip-left" data-tooltip="' +
cityssm.escapeHTML(lot.mapName) +
'">' +
'<i class="fas fa-vector-square" aria-label="' +
cityssm.escapeHTML(exports.aliases.lot) +
'"></i> ' +
cityssm.escapeHTML(lot.lotName || "(No Lot Name)") +
"</span><br />";
}
for (const occupancy of workOrder.workOrderLotOccupancies) {
for (const occupant of occupancy.lotOccupancyOccupants) {
relatedHTML +=
'<span class="has-tooltip-left" data-tooltip="' +
cityssm.escapeHTML(occupant.lotOccupantType) +
'">' +
'<i class="fas fa-user" aria-label="' +
cityssm.escapeHTML(exports.aliases.occupant) +
'"></i> ' +
cityssm.escapeHTML(occupant.occupantName || "(No Name)") +
"</span><br />";
}
}
resultsTbodyElement.insertAdjacentHTML( resultsTbodyElement.insertAdjacentHTML(
"beforeend", "beforeend",
"<tr>" + "<tr>" +
@ -76,12 +104,15 @@ declare const cityssm: cityssmGlobal;
cityssm.escapeHTML(workOrder.workOrderDescription) + cityssm.escapeHTML(workOrder.workOrderDescription) +
"</span>" + "</span>" +
"</td>") + "</td>") +
('<td class="is-nowrap"><span class="is-size-7">' +
relatedHTML +
"</span></td>") +
('<td class="is-nowrap">' + ('<td class="is-nowrap">' +
('<span data-tooltip="Open Date">' + ('<span class="has-tooltip-left" data-tooltip="Open Date">' +
'<i class="fas fa-fw fa-play" aria-label="Open Date"></i> ' + '<i class="fas fa-fw fa-play" aria-label="Open Date"></i> ' +
workOrder.workOrderOpenDateString + workOrder.workOrderOpenDateString +
"</span><br />") + "</span><br />") +
('<span data-tooltip="Close Date">' + ('<span class="has-tooltip-left" data-tooltip="Close Date">' +
'<i class="fas fa-fw fa-stop" aria-label="Close Date"></i> ' + '<i class="fas fa-fw fa-stop" aria-label="Close Date"></i> ' +
(workOrder.workOrderCloseDate (workOrder.workOrderCloseDate
? workOrder.workOrderCloseDateString ? workOrder.workOrderCloseDateString
@ -116,7 +147,8 @@ declare const cityssm: cityssmGlobal;
'<table class="table is-fullwidth is-striped is-hoverable has-sticky-header">' + '<table class="table is-fullwidth is-striped is-hoverable has-sticky-header">' +
"<thead><tr>" + "<thead><tr>" +
"<th>Work Order Number</th>" + "<th>Work Order Number</th>" +
"<th>Work Order Description</th>" + "<th>Description</th>" +
"<th>Related</th>" +
"<th>Date</th>" + "<th>Date</th>" +
'<th class="has-tooltip-bottom" data-tooltip="Completed / Total Milestones">Progress</th>' + '<th class="has-tooltip-bottom" data-tooltip="Completed / Total Milestones">Progress</th>' +
(workOrderPrints.length > 0 ? '<th class="has-width-1"></th>' : "") + (workOrderPrints.length > 0 ? '<th class="has-width-1"></th>' : "") +

View File

@ -1 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,t=exports.maps,a=document.querySelector("#searchFilter--map"),s=document.querySelector("#container--searchResults"),r=()=>{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.maps+"...</div>";let r=0;const i=document.createElement("tbody"),d=a.value.trim().toLowerCase().split(" ");for(const a of t){const t=(a.mapName+" "+a.mapDescription+" "+a.mapAddress1+" "+a.mapAddress2).toLowerCase();let s=!0;for(const e of d)if(!t.includes(e)){s=!1;break}s&&(r+=1,i.insertAdjacentHTML("beforeend",'<tr><td><a class="has-text-weight-bold" href="'+e+"/maps/"+a.mapId+'">'+cityssm.escapeHTML(a.mapName||"(No Name)")+"</a><br />"+cityssm.escapeHTML(a.mapAddress1)+'</td><td class="has-text-centered">'+(a.mapLatitude&&a.mapLongitude?'<i class="fas fa-map-marker-alt" title="Has Geographic Coordinates"></i>':"")+'</td><td class="has-text-centered">'+(a.mapSVG?'<i class="fas fa-image" title="Has Image"></i>':"")+'</td><td class="has-text-right"><a href="'+e+"/lots?mapId="+a.mapId+'">'+a.lotCount+"</a></td></tr>"))}if(s.innerHTML="",0===r)s.innerHTML='<div class="message is-info"><p class="message-body">There are no '+exports.aliases.maps.toLowerCase()+" that meet the search criteria.</p></div>";else{const e=document.createElement("table");e.className="table is-fullwidth is-striped is-hoverable has-sticky-header",e.innerHTML="<thead><tr><th>"+exports.aliases.map+'</th><th class="has-text-centered">Coordinates</th><th class="has-text-centered">Image</th><th class="has-text-right">'+exports.aliases.lot+" Count</th></tr></thead>",e.append(i),s.append(e)}};a.addEventListener("keyup",r),document.querySelector("#form--searchFilters").addEventListener("submit",e=>{e.preventDefault(),r()}),r()})(); "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,a=exports.maps,s=document.querySelector("#searchFilter--map"),t=document.querySelector("#container--searchResults"),r=()=>{t.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.maps+"...</div>";let r=0;const i=document.createElement("tbody"),d=s.value.trim().toLowerCase().split(" ");for(const s of a){const a=(s.mapName+" "+s.mapDescription+" "+s.mapAddress1+" "+s.mapAddress2).toLowerCase();let t=!0;for(const e of d)if(!a.includes(e)){t=!1;break}t&&(r+=1,i.insertAdjacentHTML("beforeend",'<tr><td><a class="has-text-weight-bold" href="'+e+"/maps/"+s.mapId+'">'+cityssm.escapeHTML(s.mapName||"(No Name)")+'</a><br /><span class="is-size-7">'+cityssm.escapeHTML(s.mapDescription)+"</span></td><td>"+(s.mapAddress1?cityssm.escapeHTML(s.mapAddress1)+"<br />":"")+(s.mapAddress2?cityssm.escapeHTML(s.mapAddress2)+"<br />":"")+(s.mapCity||s.mapProvince?cityssm.escapeHTML(s.mapCity)+", "+cityssm.escapeHTML(s.mapProvince)+"<br />":"")+(s.mapPostalCode?cityssm.escapeHTML(s.mapPostalCode):"")+"</td><td>"+cityssm.escapeHTML(s.mapPhoneNumber)+'</td><td class="has-text-centered">'+(s.mapLatitude&&s.mapLongitude?'<span data-tooltip="Has Geographic Coordinates"><i class="fas fa-map-marker-alt" aria-label="Has Geographic Coordinates"></i></span>':"")+'</td><td class="has-text-centered">'+(s.mapSVG?'<span data-tooltip="Has Image"><i class="fas fa-image" aria-label="Has Image"></i></span>':"")+'</td><td class="has-text-right"><a href="'+e+"/lots?mapId="+s.mapId+'">'+s.lotCount+"</a></td></tr>"))}if(t.innerHTML="",0===r)t.innerHTML='<div class="message is-info"><p class="message-body">There are no '+exports.aliases.maps.toLowerCase()+" that meet the search criteria.</p></div>";else{const e=document.createElement("table");e.className="table is-fullwidth is-striped is-hoverable has-sticky-header",e.innerHTML="<thead><tr><th>"+exports.aliases.map+'</th><th>Address</th><th>Phone Number</th><th class="has-text-centered">Coordinates</th><th class="has-text-centered">Image</th><th class="has-text-right">'+exports.aliases.lot+" Count</th></tr></thead>",e.append(i),t.append(e)}};s.addEventListener("keyup",r),document.querySelector("#form--searchFilters").addEventListener("submit",e=>{e.preventDefault(),r()}),r()})();

View File

@ -1 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,s=document.querySelector("main").dataset.urlPrefix,r=document.querySelector("#form--searchFilters"),a=r.querySelector("#searchFilter--workOrderMilestoneDateFilter"),t=r.querySelector("#searchFilter--workOrderMilestoneDateString"),i=document.querySelector("#container--milestoneCalendar"),o=a=>{a&&a.preventDefault(),i.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 Milestones...</div>',cityssm.postJSON(s+"/workOrders/doGetWorkOrderMilestones",r,r=>{(r=>{if(0===r.length)return void(i.innerHTML='<div class="message is-info"><p class="message-body">There are no milestones that meet the search criteria.</p></div>');i.innerHTML="";const a=cityssm.dateToString(new Date);let t,o="";for(const n of r){o!==n.workOrderMilestoneDateString&&(t&&i.append(t),(t=document.createElement("div")).className="panel",t.innerHTML='<h2 class="panel-heading">'+n.workOrderMilestoneDateString+"</h2>",o=n.workOrderMilestoneDateString);const r=document.createElement("div");r.className="panel-block is-block",!n.workOrderMilestoneCompletionDate&&n.workOrderMilestoneDateString<a&&r.classList.add("has-background-warning-light");let c="";for(const e of n.workOrderLots)c+='<i class="fas fa-vector-square" aria-label="'+cityssm.escapeHTML(exports.aliases.lot)+'"></i> '+cityssm.escapeHTML(e.lotName)+"<br />";for(const e of n.workOrderLotOccupancies)for(const s of e.lotOccupancyOccupants)c+='<span class="has-tooltip-left" data-tooltip="'+cityssm.escapeHTML(s.lotOccupantType)+'"><i class="fas fa-user" aria-label="'+cityssm.escapeHTML(exports.aliases.lotOccupancy)+'"></i> '+cityssm.escapeHTML(s.occupantName)+"</span><br />";r.innerHTML='<div class="columns"><div class="column is-narrow"><span class="icon is-small">'+(n.workOrderMilestoneCompletionDate?'<i class="fas fa-check" aria-label="Completed"></i>':'<i class="far fa-square has-text-grey" aria-label="Incomplete"></i>')+'</span></div><div class="column">'+(0===n.workOrderMilestoneTime?"":n.workOrderMilestoneTimeString+"<br />")+(n.workOrderMilestoneTypeId?"<strong>"+cityssm.escapeHTML(n.workOrderMilestoneType)+"</strong><br />":"")+'<span class="is-size-7">'+cityssm.escapeHTML(n.workOrderMilestoneDescription)+'</span></div><div class="column"><i class="fas fa-circle" style="color:'+e.getRandomColor(n.workOrderNumber)+'" aria-hidden="true"></i> <a class="has-text-weight-bold" href="'+s+"/workOrders/"+n.workOrderId+'">'+cityssm.escapeHTML(n.workOrderNumber)+'</a><br /><span class="is-size-7">'+cityssm.escapeHTML(n.workOrderDescription)+'</span></div><div class="column is-size-7">'+c+"</div></div>",t.append(r)}i.append(t)})(r.workOrderMilestones)})};a.addEventListener("change",()=>{t.disabled="date"!==a.value,o()}),t.addEventListener("change",o),r.addEventListener("submit",o),o()})(); "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,s=document.querySelector("main").dataset.urlPrefix,r=document.querySelector("#form--searchFilters"),a=r.querySelector("#searchFilter--workOrderMilestoneDateFilter"),t=r.querySelector("#searchFilter--workOrderMilestoneDateString"),i=document.querySelector("#container--milestoneCalendar"),o=a=>{a&&a.preventDefault(),i.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 Milestones...</div>',cityssm.postJSON(s+"/workOrders/doGetWorkOrderMilestones",r,r=>{(r=>{if(0===r.length)return void(i.innerHTML='<div class="message is-info"><p class="message-body">There are no milestones that meet the search criteria.</p></div>');i.innerHTML="";const a=cityssm.dateToString(new Date);let t,o="";for(const n of r){o!==n.workOrderMilestoneDateString&&(t&&i.append(t),(t=document.createElement("div")).className="panel",t.innerHTML='<h2 class="panel-heading">'+n.workOrderMilestoneDateString+"</h2>",o=n.workOrderMilestoneDateString);const r=document.createElement("div");r.className="panel-block is-block",!n.workOrderMilestoneCompletionDate&&n.workOrderMilestoneDateString<a&&r.classList.add("has-background-warning-light");let c="";for(const e of n.workOrderLots)c+='<span class="has-tooltip-left" data-tooltip="'+cityssm.escapeHTML(e.mapName)+'"><i class="fas fa-vector-square" aria-label="'+cityssm.escapeHTML(exports.aliases.lot)+'"></i> '+cityssm.escapeHTML(e.lotName)+"</span><br />";for(const e of n.workOrderLotOccupancies)for(const s of e.lotOccupancyOccupants)c+='<span class="has-tooltip-left" data-tooltip="'+cityssm.escapeHTML(s.lotOccupantType)+'"><i class="fas fa-user" aria-label="'+cityssm.escapeHTML(exports.aliases.lotOccupancy)+'"></i> '+cityssm.escapeHTML(s.occupantName)+"</span><br />";r.innerHTML='<div class="columns"><div class="column is-narrow"><span class="icon is-small">'+(n.workOrderMilestoneCompletionDate?'<i class="fas fa-check" aria-label="Completed"></i>':'<i class="far fa-square has-text-grey" aria-label="Incomplete"></i>')+'</span></div><div class="column">'+(0===n.workOrderMilestoneTime?"":n.workOrderMilestoneTimeString+"<br />")+(n.workOrderMilestoneTypeId?"<strong>"+cityssm.escapeHTML(n.workOrderMilestoneType)+"</strong><br />":"")+'<span class="is-size-7">'+cityssm.escapeHTML(n.workOrderMilestoneDescription)+'</span></div><div class="column"><i class="fas fa-circle" style="color:'+e.getRandomColor(n.workOrderNumber)+'" aria-hidden="true"></i> <a class="has-text-weight-bold" href="'+s+"/workOrders/"+n.workOrderId+'">'+cityssm.escapeHTML(n.workOrderNumber)+'</a><br /><span class="is-size-7">'+cityssm.escapeHTML(n.workOrderDescription)+'</span></div><div class="column is-size-7">'+c+"</div></div>",t.append(r)}i.append(t)})(r.workOrderMilestones)})};a.addEventListener("change",()=>{t.disabled="date"!==a.value,o()}),t.addEventListener("change",o),r.addEventListener("submit",o),o()})();

View File

@ -1 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,r=exports.workOrderPrints,s=document.querySelector("#form--searchFilters");e.initializeDatePickers(s);const a=document.querySelector("#container--searchResults"),i=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),o=document.querySelector("#searchFilter--offset"),l=()=>{const e=Number.parseInt(o.value,10);a.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 Work Orders...</div>',cityssm.postJSON(t+"/workOrders/doSearchWorkOrders",s,s=>{if(0===s.workOrders.length)return void(a.innerHTML='<div class="message is-info"><p class="message-body">There are no work orders that meet the search criteria.</p></div>');const o=document.createElement("tbody");for(const e of s.workOrders)o.insertAdjacentHTML("beforeend",'<tr><td><a class="has-text-weight-bold" href="'+t+"/workOrders/"+e.workOrderId+'">'+(e.workOrderNumber.trim()?cityssm.escapeHTML(e.workOrderNumber):"(No Number)")+"</a></td><td>"+cityssm.escapeHTML(e.workOrderType)+'<br /><span class="is-size-7">'+cityssm.escapeHTML(e.workOrderDescription)+'</span></td><td class="is-nowrap"><span data-tooltip="Open Date"><i class="fas fa-fw fa-play" aria-label="Open Date"></i> '+e.workOrderOpenDateString+'</span><br /><span data-tooltip="Close Date"><i class="fas fa-fw fa-stop" aria-label="Close Date"></i> '+(e.workOrderCloseDate?e.workOrderCloseDateString:'<span class="has-text-grey">(No Close Date)</span>')+"</span></td><td>"+(0===e.workOrderMilestoneCount?"-":e.workOrderMilestoneCompletionCount+" / "+e.workOrderMilestoneCount)+"</td>"+(r.length>0?'<td><a class="button is-small" data-tooltip="Print" href="'+t+"/print/"+r[0]+"/?workOrderId="+e.workOrderId+'" target="_blank"><i class="fas fa-print" aria-label="Print"></i></a></td>':"")+"</tr>");a.innerHTML='<table class="table is-fullwidth is-striped is-hoverable has-sticky-header"><thead><tr><th>Work Order Number</th><th>Work Order Description</th><th>Date</th><th class="has-tooltip-bottom" data-tooltip="Completed / Total Milestones">Progress</th>'+(r.length>0?'<th class="has-width-1"></th>':"")+'</tr></thead><table><div class="level"><div class="level-left"><div class="level-item has-text-weight-bold">Displaying '+(e+1).toString()+" to "+Math.min(s.count,i+e)+" of "+s.count+'</div></div><div class="level-right">'+(e>0?'<div class="level-item"><button class="button is-rounded is-link is-outlined" data-page="previous" type="button" title="Previous"><i class="fas fa-arrow-left" aria-hidden="true"></i></button></div>':"")+(i+e<s.count?'<div class="level-item"><button class="button is-rounded is-link" data-page="next" type="button" title="Next"><span>Next</span><span class="icon"><i class="fas fa-arrow-right" aria-hidden="true"></i></span></button></div>':"")+"</div></div>",a.querySelector("table").append(o),e>0&&a.querySelector("button[data-page='previous']").addEventListener("click",d),i+e<s.count&&a.querySelector("button[data-page='next']").addEventListener("click",c)})},n=()=>{o.value="0",l()},d=()=>{o.value=Math.max(Number.parseInt(o.value,10)-i,0).toString(),l()},c=()=>{o.value=(Number.parseInt(o.value,10)+i).toString(),l()},u=s.querySelectorAll("input, select");for(const e of u)e.addEventListener("change",n);s.addEventListener("submit",e=>{e.preventDefault(),n()}),l()})(); "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("main").dataset.urlPrefix,s=exports.workOrderPrints,a=document.querySelector("#form--searchFilters");e.initializeDatePickers(a);const r=document.querySelector("#container--searchResults"),o=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),i=document.querySelector("#searchFilter--offset"),l=()=>{const e=Number.parseInt(i.value,10);r.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 Work Orders...</div>',cityssm.postJSON(t+"/workOrders/doSearchWorkOrders",a,a=>{if(0===a.workOrders.length)return void(r.innerHTML='<div class="message is-info"><p class="message-body">There are no work orders that meet the search criteria.</p></div>');const i=document.createElement("tbody");for(const e of a.workOrders){let a="";for(const t of e.workOrderLots)a+='<span class="has-tooltip-left" data-tooltip="'+cityssm.escapeHTML(t.mapName)+'"><i class="fas fa-vector-square" aria-label="'+cityssm.escapeHTML(exports.aliases.lot)+'"></i> '+cityssm.escapeHTML(t.lotName||"(No Lot Name)")+"</span><br />";for(const t of e.workOrderLotOccupancies)for(const e of t.lotOccupancyOccupants)a+='<span class="has-tooltip-left" data-tooltip="'+cityssm.escapeHTML(e.lotOccupantType)+'"><i class="fas fa-user" aria-label="'+cityssm.escapeHTML(exports.aliases.occupant)+'"></i> '+cityssm.escapeHTML(e.occupantName||"(No Name)")+"</span><br />";i.insertAdjacentHTML("beforeend",'<tr><td><a class="has-text-weight-bold" href="'+t+"/workOrders/"+e.workOrderId+'">'+(e.workOrderNumber.trim()?cityssm.escapeHTML(e.workOrderNumber):"(No Number)")+"</a></td><td>"+cityssm.escapeHTML(e.workOrderType)+'<br /><span class="is-size-7">'+cityssm.escapeHTML(e.workOrderDescription)+'</span></td><td class="is-nowrap"><span class="is-size-7">'+a+'</span></td><td class="is-nowrap"><span class="has-tooltip-left" data-tooltip="Open Date"><i class="fas fa-fw fa-play" aria-label="Open Date"></i> '+e.workOrderOpenDateString+'</span><br /><span class="has-tooltip-left" data-tooltip="Close Date"><i class="fas fa-fw fa-stop" aria-label="Close Date"></i> '+(e.workOrderCloseDate?e.workOrderCloseDateString:'<span class="has-text-grey">(No Close Date)</span>')+"</span></td><td>"+(0===e.workOrderMilestoneCount?"-":e.workOrderMilestoneCompletionCount+" / "+e.workOrderMilestoneCount)+"</td>"+(s.length>0?'<td><a class="button is-small" data-tooltip="Print" href="'+t+"/print/"+s[0]+"/?workOrderId="+e.workOrderId+'" target="_blank"><i class="fas fa-print" aria-label="Print"></i></a></td>':"")+"</tr>")}r.innerHTML='<table class="table is-fullwidth is-striped is-hoverable has-sticky-header"><thead><tr><th>Work Order Number</th><th>Description</th><th>Related</th><th>Date</th><th class="has-tooltip-bottom" data-tooltip="Completed / Total Milestones">Progress</th>'+(s.length>0?'<th class="has-width-1"></th>':"")+'</tr></thead><table><div class="level"><div class="level-left"><div class="level-item has-text-weight-bold">Displaying '+(e+1).toString()+" to "+Math.min(a.count,o+e)+" of "+a.count+'</div></div><div class="level-right">'+(e>0?'<div class="level-item"><button class="button is-rounded is-link is-outlined" data-page="previous" type="button" title="Previous"><i class="fas fa-arrow-left" aria-hidden="true"></i></button></div>':"")+(o+e<a.count?'<div class="level-item"><button class="button is-rounded is-link" data-page="next" type="button" title="Next"><span>Next</span><span class="icon"><i class="fas fa-arrow-right" aria-hidden="true"></i></span></button></div>':"")+"</div></div>",r.querySelector("table").append(i),e>0&&r.querySelector("button[data-page='previous']").addEventListener("click",c),o+e<a.count&&r.querySelector("button[data-page='next']").addEventListener("click",d)})},n=()=>{i.value="0",l()},c=()=>{i.value=Math.max(Number.parseInt(i.value,10)-o,0).toString(),l()},d=()=>{i.value=(Number.parseInt(i.value,10)+o).toString(),l()},p=a.querySelectorAll("input, select");for(const e of p)e.addEventListener("change",n);a.addEventListener("submit",e=>{e.preventDefault(),n()}),l()})();

File diff suppressed because one or more lines are too long

View File

@ -44,7 +44,10 @@
if (milestone.workOrderLots.length > 0) { if (milestone.workOrderLots.length > 0) {
for (const lot of milestone.workOrderLots) { for (const lot of milestone.workOrderLots) {
%> %>
<i class="fas fa-vector-square" aria-label="<%= configFunctions.getProperty("aliases.lot") %>"></i> <%= lot.lotName %><br /> <span class="has-tooltip-right" data-tooltip="<%= lot.mapName %>">
<i class="fas fa-vector-square" aria-label="<%= configFunctions.getProperty("aliases.lot") %>"></i>
<%= lot.lotName %>
</span><br />
<% <%
} }
} }
@ -53,8 +56,10 @@
for (const occupancy of milestone.workOrderLotOccupancies) { for (const occupancy of milestone.workOrderLotOccupancies) {
for (const occupant of occupancy.lotOccupancyOccupants) { for (const occupant of occupancy.lotOccupancyOccupants) {
%> %>
<span class="has-tooltip-right" data-tooltip="<%= occupant.lotOccupantType %>">
<i class="fas fa-user" aria-label="<%= configFunctions.getProperty("aliases.occupancy") %>"></i> <i class="fas fa-user" aria-label="<%= configFunctions.getProperty("aliases.occupancy") %>"></i>
<span class="has-tooltip-right" data-tooltip="<%= occupant.lotOccupantType %>"><%= occupant.occupantName %></span><br /> <%= occupant.occupantName %>
</span><br />
<% <%
} }
} }
@ -261,7 +266,10 @@
<div class="card-content"> <div class="card-content">
<div class="media"> <div class="media">
<div class="media-left"> <div class="media-left">
<i class="fas fa-3x fa-fw fa-dollar-sign" aria-hidden="true"></i> <span class="fa-layers fa-3x fa-fw" aria-hidden="true">
<i class="fas fa-dollar-sign"></i>
<i class="fas fa-cog" data-fa-transform="shrink-8 right-8 down-5" data-fa-glow="10"></i>
</span>
</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">
@ -280,7 +288,10 @@
<div class="card-content"> <div class="card-content">
<div class="media"> <div class="media">
<div class="media-left"> <div class="media-left">
<i class="fas fa-3x fa-fw fa-user-friends" aria-hidden="true"></i> <span class="fa-layers fa-3x fa-fw" aria-hidden="true">
<i class="fas fa-user-friends"></i>
<i class="fas fa-cog" data-fa-transform="shrink-8 right-8 down-5" data-fa-glow="10"></i>
</span>
</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">
@ -297,7 +308,10 @@
<div class="card-content"> <div class="card-content">
<div class="media"> <div class="media">
<div class="media-left"> <div class="media-left">
<i class="fas fa-3x fa-fw fa-vector-square" aria-hidden="true"></i> <span class="fa-layers fa-3x fa-fw" aria-hidden="true">
<i class="fas fa-vector-square"></i>
<i class="fas fa-cog" data-fa-transform="shrink-8 right-8 down-5" data-fa-glow="10"></i>
</span>
</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">
@ -314,7 +328,10 @@
<div class="card-content"> <div class="card-content">
<div class="media"> <div class="media">
<div class="media-left"> <div class="media-left">
<i class="fas fa-3x fa-fw fa-table" aria-hidden="true"></i> <span class="fa-layers fa-3x fa-fw" aria-hidden="true">
<i class="fas fa-table"></i>
<i class="fas fa-cog" data-fa-transform="shrink-8 right-8 down-5" data-fa-glow="10"></i>
</span>
</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">

View File

@ -160,7 +160,6 @@
</div> </div>
</div> </div>
<div class="has-text-right is-hidden-print"> <div class="has-text-right is-hidden-print">
<button class="button is-primary" type="submit"> <button class="button is-primary" type="submit">
<span class="icon is-small"><i class="fas fa-save" aria-hidden="true"></i></span> <span class="icon is-small"><i class="fas fa-save" aria-hidden="true"></i></span>
@ -192,6 +191,113 @@
</div> </div>
</form> </form>
<% if (!isCreate) { %>
<% const lotSearchUrl = urlPrefix + "/lots?mapId=" + map.mapId; %>
<div class="panel mt-4">
<div class="panel-heading">
<div class="level is-mobile">
<div class="level-left">
<div class="level-item">
<h2 class="title is-5 has-text-weight-bold">
<%= configFunctions.getProperty("aliases.lot") %> Summaries
<a class="tag is-link ml-2" href="<%= lotSearchUrl %>">
<%= map.lotCount %>
</a>
</h2>
</div>
</div>
<div class="level-right">
<div class="level-item">
<a class="button is-small is-success has-text-weight-normal" href="<%=urlPrefix %>/lots/new?mapId=<%= map.mapId %>">
<span class="icon"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Create a <%= configFunctions.getProperty("aliases.lot") %></span>
</a>
</div>
<div class="level-item">
<a class="button is-small is-link has-text-weight-normal" href="<%=urlPrefix %>/reports/lots-byMapId?mapId=<%= map.mapId %>" download>
<span class="icon"><i class="fas fa-download" aria-hidden="true"></i></span>
<span>Export All</span>
</a>
</div>
</div>
</div>
</div>
<div class="panel-block is-block">
<% if (map.lotCount === 0) { %>
<div class="message is-info">
<p class="message-body">
There are no <%= configFunctions.getProperty("aliases.lots").toLowerCase() %>
associated with this <%= configFunctions.getProperty("aliases.map").toLowerCase() %>.
</p>
</div>
<% } else { %>
<div class="columns">
<div class="column">
<table class="table is-fullwidth is-striped is-hoverable">
<thead>
<tr>
<th>Type</th>
<th class="has-text-right">
<%= configFunctions.getProperty("aliases.lot") %> Count
</th>
<th class="has-text-right">Percentage</th>
</tr>
</thead>
<tbody>
<% for (const lotType of lotTypeSummary) { %>
<tr>
<td>
<a class="has-text-weight-bold" href="<%= lotSearchUrl %>&lotTypeId=<%= lotType.lotTypeId %>">
<%= lotType.lotType %>
</a>
</td>
<td class="has-text-right">
<%= lotType.lotCount %>
</td>
<td class="has-text-right">
<%= ((lotType.lotCount / map.lotCount) * 100).toFixed(1) %>%
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
<div class="column">
<table class="table is-fullwidth is-striped is-hoverable">
<thead>
<tr>
<th>Status</th>
<th class="has-text-right">
<%= configFunctions.getProperty("aliases.lot") %> Count
</th>
<th class="has-text-right">Percentage</th>
</tr>
</thead>
<tbody>
<% for (const lotStatus of lotStatusSummary) { %>
<tr>
<td>
<a class="has-text-weight-bold" href="<%= lotSearchUrl %>&lotStatusId=<%= lotStatus.lotStatusId %>">
<%= lotStatus.lotStatus %>
</a>
</td>
<td class="has-text-right">
<%= lotStatus.lotCount %>
</td>
<td class="has-text-right">
<%= ((lotStatus.lotCount / map.lotCount) * 100).toFixed(1) %>%
</td>
</tr>
<% } %>
</tbody>
</table>
</div>
</div>
<% } %>
</div>
</div>
<% } %>
<%- include('_footerA'); -%> <%- include('_footerA'); -%>
<script src="<%= urlPrefix %>/javascripts/mapEdit.min.js"></script> <script src="<%= urlPrefix %>/javascripts/mapEdit.min.js"></script>

View File

@ -139,6 +139,7 @@
<th class="has-text-right"> <th class="has-text-right">
<%= configFunctions.getProperty("aliases.lot") %> Count <%= configFunctions.getProperty("aliases.lot") %> Count
</th> </th>
<th class="has-text-right">Percentage</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -152,6 +153,9 @@
<td class="has-text-right"> <td class="has-text-right">
<%= lotType.lotCount %> <%= lotType.lotCount %>
</td> </td>
<td class="has-text-right">
<%= ((lotType.lotCount / map.lotCount) * 100).toFixed(1) %>%
</td>
</tr> </tr>
<% } %> <% } %>
</tbody> </tbody>
@ -165,6 +169,7 @@
<th class="has-text-right"> <th class="has-text-right">
<%= configFunctions.getProperty("aliases.lot") %> Count <%= configFunctions.getProperty("aliases.lot") %> Count
</th> </th>
<th class="has-text-right">Percentage</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -178,6 +183,9 @@
<td class="has-text-right"> <td class="has-text-right">
<%= lotStatus.lotCount %> <%= lotStatus.lotCount %>
</td> </td>
<td class="has-text-right">
<%= ((lotStatus.lotCount / map.lotCount) * 100).toFixed(1) %>%
</td>
</tr> </tr>
<% } %> <% } %>
</tbody> </tbody>

View File

@ -214,7 +214,7 @@
<div class="tab-container"> <div class="tab-container">
<div class="<%= (tabToSelect === "lotOccupancies" ? "" : "is-hidden") %>" id="relatedTab--lotOccupancies"> <div class="<%= (tabToSelect === "lotOccupancies" ? "" : "is-hidden") %>" id="relatedTab--lotOccupancies">
<div class="box has-background-light has-text-right p-3"> <div class="box has-background-light has-text-right p-3">
<button class="button is-success" id="button--addLotOccupancy" type="button"> <button class="button is-small is-success" id="button--addLotOccupancy" type="button">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span> <span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Related <%= configFunctions.getProperty("aliases.occupancy") %></span> <span>Add Related <%= configFunctions.getProperty("aliases.occupancy") %></span>
</button> </button>
@ -223,7 +223,7 @@
</div> </div>
<div class="<%= (tabToSelect === "lots" ? "" : "is-hidden") %>" id="relatedTab--lots"> <div class="<%= (tabToSelect === "lots" ? "" : "is-hidden") %>" id="relatedTab--lots">
<div class="box has-background-light has-text-right p-3"> <div class="box has-background-light has-text-right p-3">
<button class="button is-success" id="button--addLot" type="button"> <button class="button is-small is-success" id="button--addLot" type="button">
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span> <span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
<span>Add Related <%= configFunctions.getProperty("aliases.lot") %></span> <span>Add Related <%= configFunctions.getProperty("aliases.lot") %></span>
</button> </button>

View File

@ -75,8 +75,7 @@
</div> </div>
</div> </div>
</div> <div class="column">
<div class="field"> <div class="field">
<label class="label" for="searchFilter--workOrderOpenDateString">Open Date</label> <label class="label" for="searchFilter--workOrderOpenDateString">Open Date</label>
<div class="control is-expanded has-icons-left"> <div class="control is-expanded has-icons-left">
@ -85,7 +84,32 @@
<i class="fas fa-calendar" aria-hidden="true"></i> <i class="fas fa-calendar" aria-hidden="true"></i>
</span> </span>
</div> </div>
</div>
</div>
</div>
<div class="columns">
<div class="column">
<div class="field">
<label class="label" for="searchFilter--occupantName">Related <%= configFunctions.getProperty("aliases.occupant") %> Name</label>
<div class="control is-expanded has-icons-left">
<input class="input" id="searchFilter--occupantName" name="occupantName" type="text" />
<span class="icon is-small is-left">
<i class="fas fa-search" aria-hidden="true"></i>
</span>
</div>
</div>
</div>
<div class="column">
<div class="field">
<label class="label" for="searchFilter--lotName">Related <%= configFunctions.getProperty("aliases.lot") %> Name</label>
<div class="control is-expanded has-icons-left">
<input class="input" id="searchFilter--lotName" name="lotName" type="text" />
<span class="icon is-small is-left">
<i class="fas fa-search" aria-hidden="true"></i>
</span>
</div>
</div>
</div>
</div> </div>
</form> </form>
</div> </div>