current work order details on dashboard
parent
d639ae57a9
commit
8e64a11371
|
|
@ -1,6 +1,25 @@
|
||||||
|
import { dateToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
||||||
|
import { getWorkOrderMilestones } from "../../helpers/lotOccupancyDB/getWorkOrderMilestones.js";
|
||||||
|
import { getWorkOrders } from "../../helpers/lotOccupancyDB/getWorkOrders.js";
|
||||||
export const handler = (_request, response) => {
|
export const handler = (_request, response) => {
|
||||||
|
const currentDateString = dateToString(new Date());
|
||||||
|
const workOrderMilestones = getWorkOrderMilestones({
|
||||||
|
workOrderMilestoneDateFilter: "date",
|
||||||
|
workOrderMilestoneDateString: currentDateString
|
||||||
|
}, {
|
||||||
|
orderBy: "completion",
|
||||||
|
includeWorkOrders: true
|
||||||
|
});
|
||||||
|
const workOrderCount = getWorkOrders({
|
||||||
|
workOrderOpenDateString: currentDateString
|
||||||
|
}, {
|
||||||
|
limit: 1,
|
||||||
|
offset: 0
|
||||||
|
}).count;
|
||||||
response.render("dashboard", {
|
response.render("dashboard", {
|
||||||
headTitle: "Dashboard"
|
headTitle: "Dashboard",
|
||||||
|
workOrderMilestones,
|
||||||
|
workOrderCount
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,36 @@
|
||||||
import type { RequestHandler } from "express";
|
import type { RequestHandler } from "express";
|
||||||
|
|
||||||
|
import { dateToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
||||||
|
|
||||||
|
import { getWorkOrderMilestones } from "../../helpers/lotOccupancyDB/getWorkOrderMilestones.js";
|
||||||
|
import {getWorkOrders} from "../../helpers/lotOccupancyDB/getWorkOrders.js";
|
||||||
|
|
||||||
export const handler: RequestHandler = (_request, response) => {
|
export const handler: RequestHandler = (_request, response) => {
|
||||||
|
|
||||||
|
const currentDateString = dateToString(new Date());
|
||||||
|
|
||||||
|
const workOrderMilestones = getWorkOrderMilestones(
|
||||||
|
{
|
||||||
|
workOrderMilestoneDateFilter: "date",
|
||||||
|
workOrderMilestoneDateString: currentDateString
|
||||||
|
},
|
||||||
|
{
|
||||||
|
orderBy: "completion",
|
||||||
|
includeWorkOrders: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const workOrderCount = getWorkOrders({
|
||||||
|
workOrderOpenDateString: currentDateString
|
||||||
|
}, {
|
||||||
|
limit: 1,
|
||||||
|
offset: 0
|
||||||
|
}).count;
|
||||||
|
|
||||||
response.render("dashboard", {
|
response.render("dashboard", {
|
||||||
headTitle: "Dashboard"
|
headTitle: "Dashboard",
|
||||||
|
workOrderMilestones,
|
||||||
|
workOrderCount
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import type * as recordTypes from "../../types/recordTypes";
|
||||||
interface GetWorkOrdersFilters {
|
interface GetWorkOrdersFilters {
|
||||||
workOrderTypeId?: number | string;
|
workOrderTypeId?: number | string;
|
||||||
workOrderOpenStatus?: "" | "open" | "closed";
|
workOrderOpenStatus?: "" | "open" | "closed";
|
||||||
|
workOrderOpenDateString?: string;
|
||||||
}
|
}
|
||||||
interface GetWorkOrdersOptions {
|
interface GetWorkOrdersOptions {
|
||||||
limit: number;
|
limit: number;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
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 } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
import { dateIntegerToString, dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
||||||
export const getWorkOrders = (filters, options) => {
|
export const getWorkOrders = (filters, options) => {
|
||||||
const database = sqlite(databasePath, {
|
const database = sqlite(databasePath, {
|
||||||
readonly: true
|
readonly: true
|
||||||
|
|
@ -20,6 +20,10 @@ export const getWorkOrders = (filters, options) => {
|
||||||
sqlWhereClause += " and w.workOrderCloseDate is not null";
|
sqlWhereClause += " and w.workOrderCloseDate is not null";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (filters.workOrderOpenDateString) {
|
||||||
|
sqlWhereClause += " and w.workOrderOpenDate = ?";
|
||||||
|
sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString));
|
||||||
|
}
|
||||||
const count = database
|
const count = database
|
||||||
.prepare("select count(*) as recordCount" +
|
.prepare("select count(*) as recordCount" +
|
||||||
" from WorkOrders w" +
|
" from WorkOrders w" +
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@ import sqlite from "better-sqlite3";
|
||||||
|
|
||||||
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
|
||||||
|
|
||||||
import { dateIntegerToString } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
import { dateIntegerToString, dateStringToInteger } from "@cityssm/expressjs-server-js/dateTimeFns.js";
|
||||||
|
|
||||||
import type * as recordTypes from "../../types/recordTypes";
|
import type * as recordTypes from "../../types/recordTypes";
|
||||||
|
|
||||||
interface GetWorkOrdersFilters {
|
interface GetWorkOrdersFilters {
|
||||||
workOrderTypeId?: number | string;
|
workOrderTypeId?: number | string;
|
||||||
workOrderOpenStatus?: "" | "open" | "closed";
|
workOrderOpenStatus?: "" | "open" | "closed";
|
||||||
|
workOrderOpenDateString?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GetWorkOrdersOptions {
|
interface GetWorkOrdersOptions {
|
||||||
|
|
@ -45,6 +46,11 @@ export const getWorkOrders = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filters.workOrderOpenDateString) {
|
||||||
|
sqlWhereClause += " and w.workOrderOpenDate = ?";
|
||||||
|
sqlParameters.push(dateStringToInteger(filters.workOrderOpenDateString));
|
||||||
|
}
|
||||||
|
|
||||||
const count: number = database
|
const count: number = database
|
||||||
.prepare(
|
.prepare(
|
||||||
"select count(*) as recordCount" +
|
"select count(*) as recordCount" +
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,60 @@
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
|
<% if (workOrderMilestones.length > 0) { %>
|
||||||
|
<div class="column is-4">
|
||||||
|
<div class="panel is-info">
|
||||||
|
<h2 class="panel-heading">Today's Milestones</h2>
|
||||||
|
<% for (const milestone of workOrderMilestones) { %>
|
||||||
|
<a class="panel-block" href="<%= urlPrefix %>/workOrders/<%= milestone.workOrderId %>">
|
||||||
|
<div class="columns is-mobile">
|
||||||
|
<div class="column is-narrow">
|
||||||
|
<div class="icon is-small">
|
||||||
|
<% if (milestone.workOrderMilestoneCompletionDate) { %>
|
||||||
|
<i class="fas fa-check" aria-label="Completed"></i>
|
||||||
|
<% } else { %>
|
||||||
|
<i class="far fa-square" aria-label="Incomplete"></i>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<% if (milestone.workOrderMilestoneTime) { %>
|
||||||
|
<%= milestone.workOrderMilestoneTimeString %><br />
|
||||||
|
<% } %>
|
||||||
|
<% if (milestone.workOrderMilestoneTypeId) { %>
|
||||||
|
<strong><%= milestone.workOrderMilestoneType %></strong><br />
|
||||||
|
<% } %>
|
||||||
|
<span class="is-size-7">
|
||||||
|
<i class="fas fa-hard-hat" aria-label="Work Order"></i> <%= milestone.workOrder.workOrderNumber %><br />
|
||||||
|
<%
|
||||||
|
if (milestone.workOrder.workOrderLots.length > 0) {
|
||||||
|
for (const lot of milestone.workOrder.workOrderLots) {
|
||||||
|
%>
|
||||||
|
<i class="fas fa-vector-square" aria-label="<%= configFunctions.getProperty("aliases.lot") %>"></i> <%= lot.lotName %><br />
|
||||||
|
<%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (milestone.workOrder.workOrderLotOccupancies.length > 0) {
|
||||||
|
for (const occupancy of milestone.workOrder.workOrderLotOccupancies) {
|
||||||
|
for (const occupant of occupancy.lotOccupancyOccupants) {
|
||||||
|
%>
|
||||||
|
<i class="fas fa-user" aria-label="<%= configFunctions.getProperty("aliases.occupancy") %>"></i> <%= occupant.occupantName %><br />
|
||||||
|
<%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
<div class="column">
|
||||||
|
<div class="columns is-desktop">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
|
@ -26,21 +80,66 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<% if (user.userProperties.canUpdate) { %>
|
||||||
|
<div class="card-footer">
|
||||||
|
<a class="card-footer-item" href="<%= urlPrefix %>/lotOccupancies/new">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span>New <%= configFunctions.getProperty("aliases.occupancy") %></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="card">
|
||||||
<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-hard-hat" aria-hidden="true"></i>
|
<i class="fas fa-3x fa-fw fa-hard-hat" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-content has-text-black">
|
<div class="media-content has-text-black">
|
||||||
|
<div class="level is-marginless is-mobile">
|
||||||
|
<div class="level-left">
|
||||||
|
<div class="level-item">
|
||||||
<h2 class="title is-4 is-marginless">
|
<h2 class="title is-4 is-marginless">
|
||||||
<a href="<%= urlPrefix %>/workOrders">Work Orders</a>
|
<a href="<%= urlPrefix %>/workOrders">Work Orders</a>
|
||||||
</h2>
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% if (workOrderCount > 0) { %>
|
||||||
|
<div class="level-right">
|
||||||
|
<div class="level-item">
|
||||||
|
<span class="tag is-info"><%= workOrderCount %> Open Today</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
<p>View and maintain work orders.</p>
|
<p>View and maintain work orders.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card-footer">
|
||||||
|
<% if (user.userProperties.canUpdate) { %>
|
||||||
|
<a class="card-footer-item" href="<%= urlPrefix %>/workOrders/new">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span>New Work Order</span>
|
||||||
|
</a>
|
||||||
|
<% } %>
|
||||||
|
<a class="card-footer-item" href="<%= urlPrefix %>/workOrders/milestoneCalendar">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-calendar" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span>Milestone Calendar</span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="columns">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
|
@ -57,6 +156,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<% if (user.userProperties.canUpdate) { %>
|
||||||
|
<div class="card-footer">
|
||||||
|
<a class="card-footer-item" href="<%= urlPrefix %>/lots/new">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span>New <%= configFunctions.getProperty("aliases.lot") %></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
|
|
@ -70,6 +183,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<% if (user.userProperties.canUpdate) { %>
|
||||||
|
<div class="card-footer">
|
||||||
|
<a class="card-footer-item" href="<%= urlPrefix %>/maps/new">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fas fa-plus" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
<span>New <%= configFunctions.getProperty("aliases.map") %></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -123,8 +246,6 @@
|
||||||
<% if (user.userProperties.isAdmin) { %>
|
<% if (user.userProperties.isAdmin) { %>
|
||||||
<h2 class="title is-3">Administrator Tools</h2>
|
<h2 class="title is-3">Administrator Tools</h2>
|
||||||
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="media">
|
<div class="media">
|
||||||
|
|
@ -196,9 +317,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<% } %>
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<%- include('_footerA'); -%>
|
<%- include('_footerA'); -%>
|
||||||
<%- include('_footerB'); -%>
|
<%- include('_footerB'); -%>
|
||||||
Loading…
Reference in New Issue