From 3e5da87393dd078d3d1cea80d1d79c7d8ba0eb8e Mon Sep 17 00:00:00 2001 From: John Darragh Date: Tue, 2 Jul 2024 19:36:31 -0700 Subject: [PATCH] Make date formatting consistent (#1776) --- client/src/components/Feedback/ProjectList.js | 18 ++----- client/src/components/PdfPrint/PdfFooter.js | 44 ++++++++--------- client/src/components/PdfPrint/PdfPrint.js | 17 ++----- .../ProjectWizard/TdmCalculationContainer.js | 47 ++++++++++--------- .../ProjectWizard/TdmCalculationWizard.js | 35 ++++++++------ .../components/ProjectWizard/WizardFooter.js | 44 ++++------------- .../Projects/MultiProjectToolbarMenu.js | 24 ++++------ .../components/Projects/ProjectTableRow.js | 20 +------- .../src/components/Projects/ProjectsPage.js | 13 ----- client/src/helpers/util.js | 13 +++++ 10 files changed, 104 insertions(+), 171 deletions(-) create mode 100644 client/src/helpers/util.js diff --git a/client/src/components/Feedback/ProjectList.js b/client/src/components/Feedback/ProjectList.js index de45eb02..4645df35 100644 --- a/client/src/components/Feedback/ProjectList.js +++ b/client/src/components/Feedback/ProjectList.js @@ -1,6 +1,7 @@ import React, { useState } from "react"; import PropTypes from "prop-types"; import { createUseStyles } from "react-jss"; +import { formatDatetime } from "../../helpers/util"; const useStyles = createUseStyles({ heading3: { @@ -25,19 +26,6 @@ const ProjectsList = ({ projects, setSelectedProjects, selectedProjects }) => { })) ); - const formatDates = date => { - return new Date(date) - .toLocaleDateString("en-US", { - month: "2-digit", - day: "2-digit", - year: "numeric", - hour: "numeric", - minute: "2-digit", - hour12: true - }) - .replace(",", ""); - }; - const onSelect = event => { const value = event.target.checked; const id = Number(event.target.name); @@ -94,10 +82,10 @@ const ProjectsList = ({ projects, setSelectedProjects, selectedProjects }) => { {JSON.parse(project.formInputs)["PROJECT_ADDRESS"]} - {formatDates(project.dateCreated)} + {formatDatetime(project.dateCreated)} - {formatDates(project.dateModified)} + {formatDatetime(project.dateModified)} ))} diff --git a/client/src/components/PdfPrint/PdfFooter.js b/client/src/components/PdfPrint/PdfFooter.js index f999c783..83a34161 100644 --- a/client/src/components/PdfPrint/PdfFooter.js +++ b/client/src/components/PdfPrint/PdfFooter.js @@ -1,8 +1,9 @@ import React, { useState, useEffect, useContext } from "react"; import PropTypes from "prop-types"; import { createUseStyles } from "react-jss"; -import { DateTime } from "luxon"; import UserContext from "../../contexts/UserContext"; +import { DateTime } from "luxon"; +import { formatDatetime } from "../../helpers/util"; const useStyles = createUseStyles({ pdfTimeText: { @@ -15,23 +16,24 @@ const useStyles = createUseStyles({ } }); -const PdfFooter = ({ - dateModified, - dateSubmitted, - dateSnapshotted, - loginId -}) => { +const PdfFooter = ({ project }) => { + const { dateModified, dateSubmitted, dateSnapshotted, loginId } = project; const classes = useStyles(); const userContext = useContext(UserContext); const loggedInUserId = userContext.account?.id; + const formattedDateModified = formatDatetime(dateModified); + const formattedDateSnapshotted = formatDatetime(dateSnapshotted); + const formattedDateSubmitted = formatDatetime(dateSubmitted); - const [printedDate, setPrintedDate] = useState(DateTime.now()); + const [formattedDatePrinted, setFormattedDatePrinted] = useState( + formatDatetime(DateTime.now()) + ); useEffect(() => { // You would update these dates based on your application logic // For instance, you might fetch them from an API when the component mounts const updateDates = () => { - setPrintedDate(DateTime.now()); // replace with actual date + setFormattedDatePrinted(formatDatetime(DateTime.now())); // replace with actual date }; updateDates(); @@ -47,25 +49,25 @@ const PdfFooter = ({ <>
Status:{" "} - {!dateSnapshotted + {!formattedDateSnapshotted ? "Draft" : loginId === loggedInUserId ? "Snapshot" : "Shared Snapshot"}
- {dateSubmitted && ( + {formattedDateSubmitted && (
- Snapshot Submitted: {dateSubmitted} Pacific Time + Snapshot Submitted: {formattedDateSubmitted} Pacific Time
)} - {dateSnapshotted && ( + {formattedDateSnapshotted && (
- Snapshot Created: {dateSnapshotted} Pacific Time + Snapshot Created: {formattedDateSnapshotted} Pacific Time
)} - {dateModified && ( + {formattedDateModified && (
- Date Last Saved: {dateModified} Pacific Time + Date Last Saved: {formattedDateModified} Pacific Time
)} @@ -79,10 +81,7 @@ const PdfFooter = ({ marginBottom: "5px" }} > - Date Printed:{" "} - {printedDate - .setZone("America/Los_Angeles") - .toFormat("yyyy-MM-dd, HH:mm:ss 'Pacific Time'")} + Date Printed: {formattedDatePrinted} Los Angeles Department of Transportation | tdm.ladot.lacity.org | @@ -93,10 +92,7 @@ const PdfFooter = ({ }; PdfFooter.propTypes = { - dateModified: PropTypes.string || null, - dateSubmitted: PropTypes.string || null, - dateSnapshotted: PropTypes.string || null, - loginId: PropTypes.number || null + project: PropTypes.shape }; export default PdfFooter; diff --git a/client/src/components/PdfPrint/PdfPrint.js b/client/src/components/PdfPrint/PdfPrint.js index 70738a23..f1930ad6 100644 --- a/client/src/components/PdfPrint/PdfPrint.js +++ b/client/src/components/PdfPrint/PdfPrint.js @@ -130,8 +130,7 @@ const useStyles = createUseStyles({ export const PdfPrint = forwardRef((props, ref) => { const classes = useStyles(); - const { rules, dateModified, dateSubmitted, dateSnapshotted, loginId } = - props; + const { rules, project } = props; const level = getRule(rules, "PROJECT_LEVEL"); const targetPoints = getRule(rules, "TARGET_POINTS_PARK"); @@ -324,24 +323,14 @@ export const PdfPrint = forwardRef((props, ref) => { - + ); }); PdfPrint.propTypes = { rules: PropTypes.array, - account: PropTypes.object, - projectId: PropTypes.number || null, - loginId: PropTypes.number || null, - dateModified: PropTypes.string || null, - dateSubmitted: PropTypes.string || null, - dateSnapshotted: PropTypes.string | null + project: PropTypes.shape }; export default PdfPrint; diff --git a/client/src/components/ProjectWizard/TdmCalculationContainer.js b/client/src/components/ProjectWizard/TdmCalculationContainer.js index 0078d134..c6bbe88f 100644 --- a/client/src/components/ProjectWizard/TdmCalculationContainer.js +++ b/client/src/components/ProjectWizard/TdmCalculationContainer.js @@ -7,7 +7,7 @@ import * as ruleService from "../../services/rule.service"; import * as projectService from "../../services/project.service"; import Engine from "../../services/tdm-engine"; import { useToast } from "../../contexts/Toast"; -import { DateTime } from "luxon"; +// import { formatDatetime } from "../../helpers/util"; // These are the calculation results we want to calculate // and display on the main page. @@ -45,15 +45,18 @@ export function TdmCalculationContainer({ contentContainerRef }) { const [engine, setEngine] = useState(null); const [formInputs, setFormInputs] = useState({}); const projectId = params.projectId ? Number(params.projectId) : 0; - const [loginId, setLoginId] = useState(0); const [strategiesInitialized, setStrategiesInitialized] = useState(false); const [formHasSaved, setFormHasSaved] = useState(true); const [inapplicableStrategiesModal, setInapplicableStrategiesModal] = useState(false); const [rules, setRules] = useState([]); - const [dateModified, setDateModified] = useState(); - const [dateSnapshotted, setDateSnapshotted] = useState(); - const [dateSubmitted, setDateSubmitted] = useState(); + + const [project, setProject] = useState({}); + // const [loginId, setLoginId] = useState(0); + // const [dateModified, setDateModified] = useState(); + // const [dateSnapshotted, setDateSnapshotted] = useState(); + // const [dateSubmitted, setDateSubmitted] = useState(); + const toast = useToast(); const fetchRules = useCallback(async () => { @@ -69,14 +72,6 @@ export function TdmCalculationContainer({ contentContainerRef }) { fetchRules(); }, [fetchRules]); - const formatDate = date => { - return date - ? DateTime.fromISO(date) - .setZone("America/Los_Angeles") - .toFormat("MM/dd/yyyy h:mm a") - : null; - }; - // Initialize Engine and (if existing project), perform initial calculation. const initializeEngine = useCallback(async () => { // Only run if engine has been instantiated @@ -87,10 +82,13 @@ export function TdmCalculationContainer({ contentContainerRef }) { if (Number(projectId) > 0 && account.id) { projectResponse = await projectService.getById(projectId); - setLoginId(projectResponse.data.loginId); - setDateModified(formatDate(projectResponse.data.dateModified)); - setDateSnapshotted(formatDate(projectResponse.data?.dateSnapshotted)); - setDateSubmitted(formatDate(projectResponse.data?.dateSubmitted)); + // setLoginId(projectResponse.data.loginId); + // setDateModified(formatDatetime(projectResponse.data.dateModified)); + // setDateSnapshotted( + // formatDatetime(projectResponse.data?.dateSnapshotted) + // ); + // setDateSubmitted(formatDatetime(projectResponse.data?.dateSubmitted)); + setProject(projectResponse.data); inputs = JSON.parse(projectResponse.data.formInputs); setStrategiesInitialized(true); @@ -110,7 +108,7 @@ export function TdmCalculationContainer({ contentContainerRef }) { // const redirect = account.id ? "/projects" : "/login"; // navigate(redirect); } - }, [engine, projectId, account, setRules, setDateModified]); + }, [engine, projectId, account, setRules, setProject]); // Initialize the engine with saved project data, as appropriate. // Should run only when projectId changes. @@ -462,7 +460,8 @@ export function TdmCalculationContainer({ contentContainerRef }) { projectResponse = await projectService.getById(projectId); - setDateModified(formatDate(projectResponse.data?.dateModified)); + // setDateModified(formatDatetime(projectResponse.data?.dateModified)); + setProject(projectResponse.data); } catch (err) { console.error(err); if (err.response) { @@ -527,7 +526,6 @@ export function TdmCalculationContainer({ contentContainerRef }) { onPkgSelect={onPkgSelect} onParkingProvidedChange={onParkingProvidedChange} resultRuleCodes={resultRuleCodes} - loginId={loginId} onSave={onSave} allowResidentialPackage={allowResidentialPackage} allowSchoolPackage={allowSchoolPackage} @@ -535,12 +533,15 @@ export function TdmCalculationContainer({ contentContainerRef }) { schoolPackageSelected={schoolPackageSelected} formIsDirty={!formHasSaved} projectIsValid={projectIsValid} - dateModified={dateModified} - dateSnapshotted={dateSnapshotted} - dateSubmitted={dateSubmitted} + // loginId={loginId} + // dateModified={dateModified} + // dateSnapshotted={dateSnapshotted} + // dateSubmitted={dateSubmitted} contentContainerRef={contentContainerRef} inapplicableStrategiesModal={inapplicableStrategiesModal} closeStrategiesModal={closeStrategiesModal} + // projectId={projectId} + project={project} /> ); } diff --git a/client/src/components/ProjectWizard/TdmCalculationWizard.js b/client/src/components/ProjectWizard/TdmCalculationWizard.js index 3d190e9e..75ca82ee 100644 --- a/client/src/components/ProjectWizard/TdmCalculationWizard.js +++ b/client/src/components/ProjectWizard/TdmCalculationWizard.js @@ -45,7 +45,7 @@ const TdmCalculationWizard = props => { onPkgSelect, onParkingProvidedChange, resultRuleCodes, - loginId, + // loginId, onSave, allowResidentialPackage, allowSchoolPackage, @@ -53,12 +53,13 @@ const TdmCalculationWizard = props => { schoolPackageSelected, formIsDirty, projectIsValid, - dateModified, - dateSnapshotted, - dateSubmitted, + // dateModified, + // dateSnapshotted, + // dateSubmitted, contentContainerRef, inapplicableStrategiesModal, - closeStrategiesModal + closeStrategiesModal, + project } = props; const classes = useStyles(); const context = useContext(ToastContext); @@ -70,6 +71,7 @@ const TdmCalculationWizard = props => { const projectId = Number(params.projectId); const { pathname } = useLocation(); const [ainInputError, setAINInputError] = useState(""); + const loginId = project.loginId; /* shouldBlock determines if user should be blocked from navigating away from wizard. Note that navigation from /calculation/a/x to @@ -291,7 +293,7 @@ const TdmCalculationWizard = props => { projectId={projectId} loginId={loginId} onSave={onSave} - dateModified={dateModified} + dateModified={project.dateModified} /> ); default: @@ -318,6 +320,7 @@ const TdmCalculationWizard = props => { > {pageContents(page)} { setDisplaySaveButton={setDisplaySaveButton} setDisplayPrintButton={setDisplayPrintButton} onSave={onSave} - dateModified={dateModified} - dateSnapshotted={dateSnapshotted} - dateSubmitted={dateSubmitted} - loginId={loginId} + project={project} + // dateModified={dateModified} + // dateSnapshotted={dateSnapshotted} + // dateSubmitted={dateSubmitted} + // loginId={loginId} /> @@ -367,7 +371,7 @@ TdmCalculationWizard.propTypes = { onResetProject: PropTypes.func.isRequired, filters: PropTypes.object.isRequired, resultRuleCodes: PropTypes.array.isRequired, - loginId: PropTypes.number.isRequired, + // loginId: PropTypes.number.isRequired, onSave: PropTypes.func.isRequired, allowResidentialPackage: PropTypes.bool.isRequired, allowSchoolPackage: PropTypes.bool.isRequired, @@ -375,11 +379,12 @@ TdmCalculationWizard.propTypes = { schoolPackageSelected: PropTypes.func, formIsDirty: PropTypes.bool, projectIsValid: PropTypes.func, - dateModified: PropTypes.string, - dateSnapshotted: PropTypes.string, - dateSubmitted: PropTypes.string, + // dateModified: PropTypes.string, + // dateSnapshotted: PropTypes.string, + // dateSubmitted: PropTypes.string, inapplicableStrategiesModal: PropTypes.bool, - closeStrategiesModal: PropTypes.func + closeStrategiesModal: PropTypes.func, + project: PropTypes.shape }; export default TdmCalculationWizard; diff --git a/client/src/components/ProjectWizard/WizardFooter.js b/client/src/components/ProjectWizard/WizardFooter.js index 15d6bd30..eb4c049c 100644 --- a/client/src/components/ProjectWizard/WizardFooter.js +++ b/client/src/components/ProjectWizard/WizardFooter.js @@ -6,7 +6,7 @@ import { createUseStyles } from "react-jss"; import PrintButton from "../Button/PrintButton"; import ReactToPrint from "react-to-print"; import { PdfPrint } from "../PdfPrint/PdfPrint"; -import { DateTime } from "luxon"; +import { formatDatetime } from "../../helpers/util"; import UserContext from "../../contexts/UserContext"; const useStyles = createUseStyles({ @@ -49,10 +49,7 @@ const WizardFooter = ({ setDisplaySaveButton, setDisplayPrintButton, onSave, - dateModified, - dateSnapshotted, - dateSubmitted, - loginId + project }) => { const classes = useStyles(); const componentRef = useRef(); @@ -60,21 +57,9 @@ const WizardFooter = ({ const projectName = projectNameRule ? projectNameRule.value : "TDM Calculation Summary"; - const formattedDateSnapshotted = dateSnapshotted - ? DateTime.fromFormat(dateSnapshotted, "MM/dd/yyyy h:mm a").toFormat( - "yyyy-MM-dd, h:mm a" - ) - : null; - const formattedDateSubmitted = dateSubmitted - ? DateTime.fromFormat(dateSubmitted, "MM/dd/yyyy h:mm a").toFormat( - "yyyy-MM-dd, h:mm a" - ) - : null; - const formattedDateModified = dateModified - ? DateTime.fromFormat(dateModified, "MM/dd/yyyy h:mm a").toFormat( - "yyyy-MM-dd, h:mm a" - ) - : null; + const formattedDateSnapshotted = formatDatetime(project.dateSnapshotted); + const formattedDateSubmitted = formatDatetime(project.dateSubmitted); + const formattedDateModified = formatDatetime(project.dateModified); const userContext = useContext(UserContext); const loggedInUserId = userContext.account?.id; @@ -121,14 +106,7 @@ const WizardFooter = ({ pageStyle=".printContainer {overflow: hidden;}" />
- +
Status: - {!dateSnapshotted + {!formattedDateSnapshotted ? "Draft" - : loginId === loggedInUserId + : project.loginId === loggedInUserId ? "Snapshot" : "Shared Snapshot"}
@@ -175,7 +153,6 @@ const WizardFooter = ({ ); }; -// TODO: WizardFooter.propTypes = { classes: PropTypes.any, rules: PropTypes.any, @@ -188,10 +165,7 @@ WizardFooter.propTypes = { setDisplayPrintButton: PropTypes.any, onSave: PropTypes.any, onDownload: PropTypes.any, - dateModified: PropTypes.any, - dateSnapshotted: PropTypes.any, - dateSubmitted: PropTypes.any, - loginId: PropTypes.number + project: PropTypes.shape }; export default WizardFooter; diff --git a/client/src/components/Projects/MultiProjectToolbarMenu.js b/client/src/components/Projects/MultiProjectToolbarMenu.js index 1f87506b..6d2e83d4 100644 --- a/client/src/components/Projects/MultiProjectToolbarMenu.js +++ b/client/src/components/Projects/MultiProjectToolbarMenu.js @@ -13,7 +13,6 @@ import { import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Tooltip } from "react-tooltip"; import PdfPrint from "../PdfPrint/PdfPrint"; -import { DateTime } from "luxon"; import { useReactToPrint } from "react-to-print"; const useStyles = createUseStyles({ @@ -51,20 +50,18 @@ const MultiProjectToolbarMenu = ({ checkedProjectsStatusData, pdfProjectData }) => { - const modifiedDate = DateTime.fromISO(checkedProjectsStatusData.dateModified) - .setZone("America/Los_Angeles") - .toFormat("yyyy-MM-dd, HH:mm:ss 'Pacific Time'"); - const dateSnapshotted = DateTime.fromISO( - checkedProjectsStatusData.dateSnapshotted ?? "" - ) - .setZone("America/Los_Angeles") - .toFormat("yyyy-MM-dd, hh:mm a 'Pacific Time'"); - const printRef = useRef(null); const classes = useStyles(); const userContext = useContext(UserContext); const account = userContext.account; - const isProjectOwner = account.id === checkedProjectsStatusData.loginId; + let project = null; + if ( + checkedProjectIds.length === 1 && + Object.keys(checkedProjectsStatusData).length > 0 + ) { + project = checkedProjectsStatusData; + } + const isProjectOwner = account.id === project?.loginId; const isBtnDisabled = (projProp, criteriaProp) => { const sameDateVals = checkedProjectsStatusData[projProp] !== false; @@ -149,13 +146,12 @@ const MultiProjectToolbarMenu = ({ ) : ( "" )} - {hasPdfData() && ( + {project && hasPdfData() && (
)} diff --git a/client/src/components/Projects/ProjectTableRow.js b/client/src/components/Projects/ProjectTableRow.js index cbd019fc..0e72f379 100644 --- a/client/src/components/Projects/ProjectTableRow.js +++ b/client/src/components/Projects/ProjectTableRow.js @@ -11,7 +11,7 @@ import { faEyeSlash, faEllipsisV } from "@fortawesome/free-solid-svg-icons"; -import { DateTime } from "luxon"; +import { formatDate } from "../../helpers/util"; import { useReactToPrint } from "react-to-print"; import ProjectContextMenu from "./ProjectContextMenu"; import PdfPrint from "../PdfPrint/PdfPrint"; @@ -56,12 +56,6 @@ const ProjectTableRow = ({ checkedProjectIds }) => { const classes = useStyles(); - const modifiedDate = DateTime.fromISO(project.dateModified) - .setZone("America/Los_Angeles") - .toFormat("yyyy-MM-dd, HH:mm:ss 'Pacific Time'"); - const dateSubmitted = DateTime.fromISO(project.dateSubmitted ?? "") - .setZone("America/Los_Angeles") - .toFormat("yyyy-MM-dd, hh:mm a 'Pacific Time'"); const formInputs = JSON.parse(project.formInputs); const printRef = useRef(); @@ -89,10 +83,6 @@ const ProjectTableRow = ({ return value !== "undefined" ? value : ""; }; - const formatDate = date => { - return new Date(date).toISOString().split("T")[0]; - }; - // Last Modified Date column should display the Last Modified date, unless the project is // deleted, in which case it will show the deleted date followed by "-Deleted" in red. const dateModifiedDisplay = () => { @@ -184,13 +174,7 @@ const ProjectTableRow = ({ )}
- +
)} diff --git a/client/src/components/Projects/ProjectsPage.js b/client/src/components/Projects/ProjectsPage.js index 5bf42be6..d12f6780 100644 --- a/client/src/components/Projects/ProjectsPage.js +++ b/client/src/components/Projects/ProjectsPage.js @@ -841,19 +841,6 @@ const ProjectsPage = ({ contentContainerRef }) => { /> )} - {/*
- {rules ? ( - - ) : ( -
- )} -
*/} diff --git a/client/src/helpers/util.js b/client/src/helpers/util.js new file mode 100644 index 00000000..019157d9 --- /dev/null +++ b/client/src/helpers/util.js @@ -0,0 +1,13 @@ +import { DateTime } from "luxon"; + +export const formatDate = date => { + return date ? new Date(date).toISOString().split("T")[0] : null; +}; + +export const formatDatetime = datetime => { + return datetime + ? DateTime.fromISO(datetime) + .setZone("America/Los_Angeles") + .toFormat("MM/dd/yyyy h:mm a") + : null; +};