diff --git a/client/src/components/form-date-time-picker-enhanced/form-date-time-picker-enhanced.component.jsx b/client/src/components/form-date-time-picker-enhanced/form-date-time-picker-enhanced.component.jsx
deleted file mode 100644
index cdabfdfb5..000000000
--- a/client/src/components/form-date-time-picker-enhanced/form-date-time-picker-enhanced.component.jsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import { DatePicker } from "antd";
-import dayjs from "../../utils/day.js";
-import React, { useRef } from "react";
-
-import { connect } from "react-redux";
-import { createStructuredSelector } from "reselect";
-import { selectBodyshop } from "../../redux/user/user.selectors.js";
-
-const mapStateToProps = createStructuredSelector({
- bodyshop: selectBodyshop
-});
-const mapDispatchToProps = (dispatch) => ({
- //setUserLanguage: language => dispatch(setUserLanguage(language))
-});
-
-const dateFormat = "MM/DD/YYYY h:mm a";
-
-export function FormDateTimePickerEnhanced({
- bodyshop,
- value,
- onBlur,
- onlyFuture,
- onlyToday,
- isDateOnly = true,
- ...restProps
-}) {
- const ref = useRef();
- return (
-
- {
- if (onlyToday) {
- return !dayjs().isSame(d, "day");
- } else if (onlyFuture) {
- return dayjs().subtract(1, "day").isAfter(d);
- }
- }}
- {...restProps}
- />
-
- );
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(FormDateTimePickerEnhanced);
diff --git a/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx b/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx
index c1bf6f749..90f5fc16d 100644
--- a/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx
+++ b/client/src/components/form-date-time-picker/form-date-time-picker.component.jsx
@@ -1,205 +1,135 @@
-import React, { forwardRef, useState } from "react";
+import React, { useCallback, useState } from "react";
import { DatePicker } from "antd";
import dayjs from "../../utils/day";
+import { formats, shorthandFormats } from "./formats.js";
+import PropTypes from "prop-types";
-// To be used as a form element only.
-
-const DateTimePicker = (
- { value, onChange, onBlur, id, onlyFuture, onlyToday, isDateOnly = false, ...restProps },
- ref
-) => {
+const DateTimePicker = ({ value, onChange, onBlur, id, onlyFuture, onlyToday, isDateOnly = false, ...restProps }) => {
const [isManualInput, setIsManualInput] = useState(false);
- const handleChange = (newDate) => {
- if (newDate && onChange) {
- onChange(newDate);
- }
- setIsManualInput(false); // Reset the manual input flag when using GUI
- };
-
- const handleKeyDown = (e) => {
- setIsManualInput(true); // User is typing, so set the manual input flag
-
- if (e.key.toLowerCase() === "t") {
- if (onChange) {
- onChange(dayjs());
+ const handleChange = useCallback(
+ (newDate) => {
+ if (newDate === null && onChange) {
+ onChange(null);
+ } else if (newDate && onChange) {
+ onChange(newDate);
}
- } else if (e.key.toLowerCase() === "enter") {
- handleBlur(e);
- }
- };
+ setIsManualInput(false);
+ },
+ [onChange]
+ );
- const handleBlur = (e) => {
- if (!isManualInput) {
- // If the input is not manual, skip the format processing
- return;
- }
+ const handleBlur = useCallback(
+ (e) => {
+ if (!isManualInput) {
+ return;
+ }
- setIsManualInput(false); // Reset the flag after processing
+ setIsManualInput(false);
- const v = e.target.value;
- if (!v) return;
+ const v = e.target.value;
+ if (!v) return;
- // Convert input to uppercase to handle 'am/pm' as well as 'AM/PM'
- const upperV = v.toUpperCase();
+ const upperV = v.toUpperCase();
- let _a;
+ let _a;
- // Handling common shorthand datetime inputs
- const shorthandFormats = [
- "M/D/YY hA",
- "M/D/YY h:mmA",
- "M/D/YYYY hA",
- "M/D/YYYY h:mmA",
- "M/D/YY ha",
- "M/D/YY h:mma",
- "M/D/YYYY ha",
- "M/D/YYYY h:mma"
- ];
-
- for (let format of shorthandFormats) {
- _a = dayjs(upperV, format);
- if (_a.isValid()) break;
- }
-
- // If shorthand parsing didn't work, fall back to existing formats
- if (!_a || !_a.isValid()) {
- const formats = [
- "MMDDYY",
- "MMDDYYYY",
- "MM/DD/YY",
- "MM/DD/YYYY",
- "M/DD/YY",
- "M/DD/YYYY",
- "MM/D/YY",
- "MM/D/YYYY",
- "M/D/YY",
- "M/D/YYYY",
- "D/MM/YY",
- "D/MM/YYYY",
- "DD/M/YY",
- "DD/M/YYYY",
- "D/M/YY",
- "D/M/YYYY",
- "MMDDYY hh:mm A",
- "MMDDYYYY hh:mm A",
- "MM/DD/YY hh:mm A",
- "MM/DD/YYYY hh:mm A",
- "M/DD/YY hh:mm A",
- "M/DD/YYYY hh:mm A",
- "MM/D/YY hh:mm A",
- "MM/D/YYYY hh:mm A",
- "M/D/YY hh:mm A",
- "M/D/YYYY hh:mm A",
- "D/MM/YY hh:mm A",
- "D/MM/YYYY hh:mm A",
- "DD/M/YY hh:mm A",
- "DD/M/YYYY hh:mm A",
- "D/M/YY hh:mm A",
- "D/M/YYYY hh:mm A",
- "MMDDYY hh:mm:ss A",
- "MMDDYYYY hh:mm:ss A",
- "MM/DD/YY hh:mm:ss A",
- "MM/DD/YYYY hh:mm:ss A",
- "M/DD/YY hh:mm:ss A",
- "M/DD/YYYY hh:mm:ss A",
- "MM/D/YY hh:mm:ss A",
- "MM/D/YYYY hh:mm:ss A",
- "M/D/YY hh:mm:ss A",
- "M/D/YYYY hh:mm:ss A",
- "D/MM/YY hh:mm:ss A",
- "D/MM/YYYY hh:mm:ss A",
- "DD/M/YY hh:mm:ss A",
- "DD/M/YYYY hh:mm:ss A",
- "D/M/YY hh:mm:ss A",
- "D/M/YYYY hh:mm:ss A",
- "MMDDYY HH:mm",
- "MMDDYYYY HH:mm",
- "MM/DD/YY HH:mm",
- "MM/DD/YYYY HH:mm",
- "M/DD/YY HH:mm",
- "M/DD/YYYY HH:mm",
- "MM/D/YY HH:mm",
- "MM/D/YYYY HH:mm",
- "M/D/YY HH:mm",
- "M/D/YYYY HH:mm",
- "D/MM/YY HH:mm",
- "D/MM/YYYY HH:mm",
- "DD/M/YY HH:mm",
- "DD/M/YYYY HH:mm",
- "D/M/YY HH:mm",
- "D/M/YYYY HH:mm",
- "MMDDYY HH:mm:ss",
- "MMDDYYYY HH:mm:ss",
- "MM/DD/YY HH:mm:ss",
- "MM/DD/YYYY HH:mm:ss",
- "M/DD/YY HH:mm:ss",
- "M/DD/YYYY HH:mm:ss",
- "MM/D/YY HH:mm:ss",
- "MM/D/YYYY HH:mm:ss",
- "M/D/YY HH:mm:ss",
- "M/D/YYYY HH:mm:ss",
- "D/MM/YY HH:mm:ss",
- "D/MM/YYYY HH:mm:ss",
- "DD/M/YY HH:mm:ss",
- "DD/M/YYYY HH:mm:ss",
- "D/M/YY HH:mm:ss",
- "D/M/YYYY HH:mm:ss"
- ];
-
- for (let format of formats) {
+ for (const format of shorthandFormats) {
_a = dayjs(upperV, format);
if (_a.isValid()) break;
}
- }
- if (_a && _a.isValid()) {
- if (isDateOnly) {
- _a = _a.startOf("day"); // Only apply startOf("day") when isDateOnly is true
- }
-
- if (value && value.isValid && value.isValid()) {
- _a.set({
- hours: value.hours(),
- minutes: value.minutes(),
- seconds: value.seconds(),
- milliseconds: value.milliseconds()
- });
- }
-
- if (onlyFuture) {
- if (dayjs().subtract(1, "day").isBefore(_a)) {
- onChange(_a);
- } else {
- onChange(dayjs().startOf("day"));
+ if (!_a || !_a.isValid()) {
+ for (const format of formats) {
+ _a = dayjs(upperV, format);
+ if (_a.isValid()) break;
}
- } else {
- onChange(_a);
}
- }
- };
+
+ if (_a && _a.isValid()) {
+ if (isDateOnly) {
+ _a = _a.startOf("day");
+ }
+
+ if (value && value.isValid && value.isValid()) {
+ _a.set({
+ hours: value.hours(),
+ minutes: value.minutes(),
+ seconds: value.seconds(),
+ milliseconds: value.milliseconds()
+ });
+ }
+
+ if (onlyFuture) {
+ if (dayjs().subtract(1, "day").isBefore(_a)) {
+ onChange(_a);
+ } else {
+ onChange(dayjs().startOf("day"));
+ }
+ } else {
+ onChange(_a);
+ }
+ }
+ },
+ [isManualInput, isDateOnly, onlyFuture, onChange, value]
+ );
+
+ const handleKeyDown = useCallback(
+ (e) => {
+ setIsManualInput(true);
+
+ if (e.key.toLowerCase() === "t" && onChange) {
+ onChange(dayjs());
+ } else if (e.key.toLowerCase() === "enter") {
+ handleBlur(e);
+ }
+ },
+ [onChange, handleBlur]
+ );
+
+ const handleDisabledDate = useCallback(
+ (current) => {
+ if (onlyToday) {
+ return !dayjs().isSame(current, "day");
+ } else if (onlyFuture) {
+ return dayjs().subtract(1, "day").isAfter(current);
+ }
+ return false;
+ },
+ [onlyToday, onlyFuture]
+ );
return (
{
- if (onlyToday) {
- return !dayjs().isSame(d, "day");
- } else if (onlyFuture) {
- return dayjs().subtract(1, "day").isAfter(d);
- }
- return false;
- }}
+ disabledDate={handleDisabledDate}
{...restProps}
/>
);
};
-export default forwardRef(DateTimePicker);
+DateTimePicker.propTypes = {
+ value: PropTypes.any,
+ onChange: PropTypes.func,
+ onBlur: PropTypes.func,
+ id: PropTypes.string,
+ onlyFuture: PropTypes.bool,
+ onlyToday: PropTypes.bool,
+ isDateOnly: PropTypes.bool
+};
+
+export default React.memo(DateTimePicker);
diff --git a/client/src/components/form-date-time-picker/formats.js b/client/src/components/form-date-time-picker/formats.js
new file mode 100644
index 000000000..7683f9990
--- /dev/null
+++ b/client/src/components/form-date-time-picker/formats.js
@@ -0,0 +1,93 @@
+export const shorthandFormats = [
+ "M/D/YY hA",
+ "M/D/YY h:mmA",
+ "M/D/YYYY hA",
+ "M/D/YYYY h:mmA",
+ "M/D/YY ha",
+ "M/D/YY h:mma",
+ "M/D/YYYY ha",
+ "M/D/YYYY h:mma"
+];
+
+export const formats = [
+ "MMDDYY",
+ "MMDDYYYY",
+ "MM/DD/YY",
+ "MM/DD/YYYY",
+ "M/DD/YY",
+ "M/DD/YYYY",
+ "MM/D/YY",
+ "MM/D/YYYY",
+ "M/D/YY",
+ "M/D/YYYY",
+ "D/MM/YY",
+ "D/MM/YYYY",
+ "DD/M/YY",
+ "DD/M/YYYY",
+ "D/M/YY",
+ "D/M/YYYY",
+ "MMDDYY hh:mm A",
+ "MMDDYYYY hh:mm A",
+ "MM/DD/YY hh:mm A",
+ "MM/DD/YYYY hh:mm A",
+ "M/DD/YY hh:mm A",
+ "M/DD/YYYY hh:mm A",
+ "MM/D/YY hh:mm A",
+ "MM/D/YYYY hh:mm A",
+ "M/D/YY hh:mm A",
+ "M/D/YYYY hh:mm A",
+ "D/MM/YY hh:mm A",
+ "D/MM/YYYY hh:mm A",
+ "DD/M/YY hh:mm A",
+ "DD/M/YYYY hh:mm A",
+ "D/M/YY hh:mm A",
+ "D/M/YYYY hh:mm A",
+ "MMDDYY hh:mm:ss A",
+ "MMDDYYYY hh:mm:ss A",
+ "MM/DD/YY hh:mm:ss A",
+ "MM/DD/YYYY hh:mm:ss A",
+ "M/DD/YY hh:mm:ss A",
+ "M/DD/YYYY hh:mm:ss A",
+ "MM/D/YY hh:mm:ss A",
+ "MM/D/YYYY hh:mm:ss A",
+ "M/D/YY hh:mm:ss A",
+ "M/D/YYYY hh:mm:ss A",
+ "D/MM/YY hh:mm:ss A",
+ "D/MM/YYYY hh:mm:ss A",
+ "DD/M/YY hh:mm:ss A",
+ "DD/M/YYYY hh:mm:ss A",
+ "D/M/YY hh:mm:ss A",
+ "D/M/YYYY hh:mm:ss A",
+ "MMDDYY HH:mm",
+ "MMDDYYYY HH:mm",
+ "MM/DD/YY HH:mm",
+ "MM/DD/YYYY HH:mm",
+ "M/DD/YY HH:mm",
+ "M/DD/YYYY HH:mm",
+ "MM/D/YY HH:mm",
+ "MM/D/YYYY HH:mm",
+ "M/D/YY HH:mm",
+ "M/D/YYYY HH:mm",
+ "D/MM/YY HH:mm",
+ "D/MM/YYYY HH:mm",
+ "DD/M/YY HH:mm",
+ "DD/M/YYYY HH:mm",
+ "D/M/YY HH:mm",
+ "D/M/YYYY HH:mm",
+ "MMDDYY HH:mm:ss",
+ "MMDDYYYY HH:mm:ss",
+ "MM/DD/YY HH:mm:ss",
+ "MM/DD/YYYY HH:mm:ss",
+ "M/DD/YY HH:mm:ss",
+ "M/DD/YYYY HH:mm:ss",
+ "MM/D/YY HH:mm:ss",
+ "MM/D/YYYY HH:mm:ss",
+ "M/D/YY HH:mm:ss",
+ "M/D/YYYY HH:mm:ss",
+ "D/MM/YY HH:mm:ss",
+ "D/MM/YYYY HH:mm:ss",
+ "DD/M/YY HH:mm:ss",
+ "DD/M/YYYY HH:mm:ss",
+ "D/M/YY HH:mm:ss",
+ "D/M/YYYY HH:mm:ss"
+];
diff --git a/client/src/components/task-upsert-modal/task-upsert-modal.component.jsx b/client/src/components/task-upsert-modal/task-upsert-modal.component.jsx
index 7d498efc3..562141a40 100644
--- a/client/src/components/task-upsert-modal/task-upsert-modal.component.jsx
+++ b/client/src/components/task-upsert-modal/task-upsert-modal.component.jsx
@@ -7,7 +7,6 @@ import dayjs from "../../utils/day";
import { connect } from "react-redux";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component.jsx";
import JobSearchSelectComponent from "../job-search-select/job-search-select.component.jsx";
-import { FormDateTimePickerEnhanced } from "../form-date-time-picker-enhanced/form-date-time-picker-enhanced.component.jsx";
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx";
const mapStateToProps = createStructuredSelector({
@@ -279,12 +278,7 @@ export function TaskUpsertModalComponent({
}
]}
>
-
+