Skip to content

Commit

Permalink
Merge pull request #986 from snoesberger/614-use-reactdatepicker
Browse files Browse the repository at this point in the history
Replace MUI DatePicker with react-datepicker
  • Loading branch information
Arnei authored Jan 6, 2025
2 parents 9a2fe20 + 55db4a1 commit db02d14
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 168 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";
import cn from "classnames";
import _ from "lodash";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import DatePicker from "react-datepicker";
import { Formik, FormikErrors, FormikProps } from "formik";
import { Field } from "../../../shared/Field";
import Notifications from "../../../shared/Notifications";
Expand Down Expand Up @@ -195,12 +195,12 @@ const EventDetailsSchedulingTab = ({
: [];

return {
scheduleStartDate: startDate.setHours(0, 0, 0).toString(),
scheduleStartDate: startDate.toString(),
scheduleStartHour: source.start.hour != null ? makeTwoDigits(source.start.hour) : "",
scheduleStartMinute: source.start.minute != null ? makeTwoDigits(source.start.minute) : "",
scheduleDurationHours: source.duration.hour != null ? makeTwoDigits(source.duration.hour) : "",
scheduleDurationMinutes: source.duration.minute != null ? makeTwoDigits(source.duration.minute): "",
scheduleEndDate: endDate.setHours(0, 0, 0).toString(),
scheduleEndDate: endDate.toString(),
scheduleEndHour: source.end.hour != null ? makeTwoDigits(source.end.hour): "",
scheduleEndMinute: source.end.minute != null ? makeTwoDigits(source.end.minute): "",
captureAgent: source.device.name,
Expand Down Expand Up @@ -286,8 +286,7 @@ const EventDetailsSchedulingTab = ({
/* date picker for start date */
<DatePicker
name="scheduleStartDate"
// tabIndex={1}
value={new Date(formik.values.scheduleStartDate)}
selected={new Date(formik.values.scheduleStartDate)}
onChange={(value: Date | null) =>
value && changeStartDate(
value,
Expand All @@ -297,6 +296,14 @@ const EventDetailsSchedulingTab = ({
checkConflictsWrapper
)
}
showYearDropdown
showMonthDropdown
yearDropdownItemNumber={2}
dateFormat="P"
popperClassName="datepicker-custom"
className="datepicker-custom-input"
portalId="root"
locale={currentLanguage?.dateLocale}
/>
) : (
<>
Expand Down
22 changes: 19 additions & 3 deletions src/components/events/partials/ModalTabsAndPages/NewSourcePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import cn from "classnames";
import Notifications from "../../../shared/Notifications";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import DatePicker from "react-datepicker";
import {
getCurrentLanguageInformation,
getTimezoneOffset,
Expand Down Expand Up @@ -444,7 +444,7 @@ const Schedule = <T extends {
<td>
<DatePicker
name="scheduleStartDate"
value={typeof formik.values.scheduleStartDate === "string" ? parseISO(formik.values.scheduleStartDate): formik.values.scheduleStartDate}
selected={typeof formik.values.scheduleStartDate === "string" ? parseISO(formik.values.scheduleStartDate): formik.values.scheduleStartDate}
onChange={(value) => {
if (formik.values.sourceMode === "SCHEDULE_MULTIPLE") {
value && changeStartDateMultiple(
Expand All @@ -460,6 +460,14 @@ const Schedule = <T extends {
);
}
}}
showYearDropdown
showMonthDropdown
yearDropdownItemNumber={2}
dateFormat="P"
popperClassName="datepicker-custom"
className="datepicker-custom-input"
portalId="root"
locale={currentLanguage?.dateLocale}
/>
</td>
</tr>
Expand All @@ -474,14 +482,22 @@ const Schedule = <T extends {
<td>
<DatePicker
name="scheduleEndDate"
value={typeof formik.values.scheduleEndDate === "string" ? parseISO(formik.values.scheduleEndDate) : formik.values.scheduleEndDate}
selected={typeof formik.values.scheduleEndDate === "string" ? parseISO(formik.values.scheduleEndDate) : formik.values.scheduleEndDate}
onChange={(value) =>
value && changeEndDateMultiple(
value,
formik.values,
formik.setFieldValue
)
}
showYearDropdown
showMonthDropdown
yearDropdownItemNumber={2}
dateFormat="P"
popperClassName="datepicker-custom"
className="datepicker-custom-input"
portalId="root"
locale={currentLanguage?.dateLocale}
/>
</td>
</tr>
Expand Down
174 changes: 50 additions & 124 deletions src/components/shared/TableFilters.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useRef, useState, useEffect } from "react";
import React, { useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import DatePicker from "react-datepicker";
import {
getFilters,
getSecondFilter,
Expand All @@ -26,6 +26,7 @@ import { useHotkeys } from "react-hotkeys-hook";
import moment from "moment";
import { AppThunk, useAppDispatch, useAppSelector } from "../../store";
import { renderValidDate } from "../../utils/dateUtils";
import { getCurrentLanguageInformation } from "../../utils/utils";
import { Tooltip } from "./Tooltip";
import DropDown from "./DropDown";
import { AsyncThunk } from "@reduxjs/toolkit";
Expand Down Expand Up @@ -146,77 +147,34 @@ const TableFilters = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [itemValue]);

// Set the sate of startDate and endDate picked with datepicker
const handleDatepickerChange = async (date: Date | null, isStart = false) => {
if (date === null) {
return;
}

if (isStart) {
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
setStartDate(date);
} else {
date.setHours(23);
date.setMinutes(59);
date.setSeconds(59);
setEndDate(date);
}
};

// If both dates are set, set the value for the startDate filter
// If the just changed, it can be passed here so we don't have wait a render
// cycle for the useState state to update
const handleDatepickerConfirm = async (date?: Date | null, isStart = false) => {
if (date === null) {
return;
}

let myStartDate = startDate;
let myEndDate = endDate;
if (date && isStart) {
myStartDate = date;
myStartDate.setHours(0);
myStartDate.setMinutes(0);
myStartDate.setSeconds(0);
}
if (date && !isStart) {
myEndDate = date;
myEndDate.setHours(23);
myEndDate.setMinutes(59);
myEndDate.setSeconds(59);
}

if (myStartDate && myEndDate && moment(myStartDate).isValid() && moment(myEndDate).isValid()) {
let filter = filterMap.find(({ name }) => name === selectedFilter);
if (filter) {
dispatch(editFilterValue({
filterName: filter.name,
value: myStartDate.toISOString() + "/" + myEndDate.toISOString()
}));
setFilterSelector(false);
dispatch(removeSelectedFilter());
// Reload of resource after going to very first page.
dispatch(goToPage(0))
await dispatch(loadResource());
dispatch(loadResourceIntoTable());
const handleDatepicker = async (dates?: [Date | undefined | null, Date | undefined | null]) => {
if (dates != null) {
let [start, end] = dates;

start?.setHours(0);
start?.setMinutes(0);
start?.setSeconds(0)
end?.setHours(23);
end?.setMinutes(59);
end?.setSeconds(59);

if (start && end && moment(start).isValid() && moment(end).isValid()) {
let filter = filterMap.find(({ name }) => name === selectedFilter);
if (filter) {
dispatch(editFilterValue({
filterName: filter.name,
value: start.toISOString() + "/" + end.toISOString()
}));
setFilterSelector(false);
dispatch(removeSelectedFilter());
// Reload of resource after going to very first page.
dispatch(goToPage(0))
await dispatch(loadResource());
dispatch(loadResourceIntoTable());
}
}
}

if (myStartDate && isStart && !endDate) {
let tmp = new Date(myStartDate.getTime());
tmp.setHours(23);
tmp.setMinutes(59);
tmp.setSeconds(59);
setEndDate(tmp);
}
if (myEndDate && !isStart && !startDate) {
let tmp = new Date(myEndDate.getTime());
tmp.setHours(0);
tmp.setMinutes(0);
tmp.setSeconds(0);
setStartDate(tmp);
if (start) setStartDate(start);
if (end) setEndDate(end);
}
}

Expand Down Expand Up @@ -315,8 +273,7 @@ const TableFilters = ({
secondFilter={secondFilter}
startDate={startDate}
endDate={endDate}
handleDate={handleDatepickerChange}
handleDateConfirm={handleDatepickerConfirm}
handleDate={handleDatepicker}
handleChange={handleChange}
openSecondFilterMenu={openSecondFilterMenu}
setOpenSecondFilterMenu={setOpenSecondFilterMenu}
Expand Down Expand Up @@ -398,7 +355,6 @@ const FilterSwitch = ({
startDate,
endDate,
handleDate,
handleDateConfirm,
secondFilter,
openSecondFilterMenu,
setOpenSecondFilterMenu,
Expand All @@ -407,17 +363,13 @@ const FilterSwitch = ({
handleChange: (name: string, value: string) => void,
startDate: Date | undefined,
endDate: Date | undefined,
handleDate: (date: Date | null, isStart?: boolean) => void,
handleDateConfirm: (date: Date | undefined | null, isStart?: boolean) => void,
handleDate: (dates: [Date | undefined | null, Date | undefined | null]) => void,
secondFilter: string,
openSecondFilterMenu: boolean,
setOpenSecondFilterMenu: (open: boolean) => void,
}) => {
const { t } = useTranslation();

const startDateRef = useRef<HTMLInputElement>(null);
const endDateRef = useRef<HTMLInputElement>(null);

if (!filter) {
return null;
}
Expand Down Expand Up @@ -471,51 +423,25 @@ const FilterSwitch = ({
case "period":
return (
<div>
{/* Show datepicker for start date */}
<DatePicker
autoFocus={true}
inputRef={startDateRef}
className="small-search start-date"
value={startDate ?? null}
format="dd/MM/yyyy"
onChange={(date) => handleDate(date as Date | null, true)}
// FixMe: onAccept does not trigger if the already set value is the same as the selected value
// This prevents us from confirming from confirming our filter, if someone wants to selected the same
// day for both start and end date (since we automatically set one to the other)
onAccept={(e) => {handleDateConfirm(e as Date | null, true)}}
slotProps={{
textField: {
onKeyDown: (event) => {
if (event.key === "Enter") {
handleDateConfirm(undefined, true)
if (endDateRef.current && startDate && moment(startDate).isValid()) {
endDateRef.current.focus();
}
}
},
},
}}
/>
<DatePicker
inputRef={endDateRef}
className="small-search end-date"
value={endDate ?? null}
format="dd/MM/yyyy"
onChange={(date) => handleDate(date as Date | null)}
// FixMe: See above
onAccept={(e) => handleDateConfirm(e as Date | null, false)}
slotProps={{
textField: {
onKeyDown: (event) => {
if (event.key === "Enter") {
handleDateConfirm(undefined, false)
if (startDateRef.current && endDate && moment(endDate).isValid()) {
startDateRef.current.focus();
}
}
},
},
}}
startOpen
autoFocus
selected={startDate}
onChange={(dates) => handleDate(dates)}
startDate={startDate}
endDate={endDate}
selectsRange
showYearDropdown
showMonthDropdown
yearDropdownItemNumber={2}
swapRange
allowSameDay
dateFormat="P"
popperPlacement="bottom"
popperClassName="datepicker-custom"
className="datepicker-custom-input"
locale={getCurrentLanguageInformation()?.dateLocale}

/>
</div>
);
Expand Down
Loading

0 comments on commit db02d14

Please sign in to comment.