From 659761a39ae28c86c8f17775faf6af16fe56a0c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Vital?= Date: Fri, 11 Jul 2025 11:08:52 -0600 Subject: [PATCH 01/14] feat: Add date processing to onCloseCallback to both custom date datepickers --- .../ExportSettingsPopup.tsx | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx index 87bb5e388e..9acbefd756 100644 --- a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx +++ b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx @@ -1,13 +1,14 @@ -import { useTranslation } from 'react-i18next'; +import { Button } from '@mui/material'; import { addDays, endOfDay, startOfDay } from 'date-fns'; -import { useFormContext } from 'react-hook-form'; import { useMemo } from 'react'; -import { Button } from '@mui/material'; +import { useFormContext } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; -import { Svg } from 'shared/components/Svg'; -import { CheckboxController, SelectController } from 'shared/components/FormComponents'; import { DatePicker } from 'shared/components/DatePicker'; +import { DateType } from 'shared/components/DatePicker/DatePicker.types'; +import { CheckboxController, SelectController } from 'shared/components/FormComponents'; import { Modal } from 'shared/components/Modal'; +import { Svg } from 'shared/components/Svg'; import { StyledBodyLarge, StyledFlexAllCenter, @@ -17,15 +18,14 @@ import { theme, } from 'shared/styles'; import { SelectEvent } from 'shared/types'; -import { DateType } from 'shared/components/DatePicker/DatePicker.types'; -import { ExportSettingsPopupProps } from './ExportSettingsPopup.types'; -import { getDataExportedOptions, getDateTypeOptions } from './ExportSettingsPopup.utils'; import { ExportDataFormValues, ExportDateType, SupplementaryFilesFormValues, } from '../../ExportDataSetting.types'; +import { ExportSettingsPopupProps } from './ExportSettingsPopup.types'; +import { getDataExportedOptions, getDateTypeOptions } from './ExportSettingsPopup.utils'; export const ExportSettingsPopup = ({ isOpen, @@ -57,19 +57,22 @@ export const ExportSettingsPopup = ({ }, }; - const onFromDateSubmit = (date: DateType) => { + const processFromDate = (date: DateType | undefined) => { if (!date) return; setValue('fromDate', startOfDay(date)); }; - const onToDateSubmit = (date: DateType) => { + + const processToDate = (date: DateType | undefined) => { if (!date) return; setValue('toDate', endOfDay(date)); }; + const onDatePickerClose = () => { if (toDate < fromDate) { setValue('toDate', addDays(fromDate, 1)); } }; + const onDateTypeChange = (e: SelectEvent) => { const dateType = e.target.value as ExportDateType; const maxDate = getMaxDate(); @@ -144,8 +147,11 @@ export const ExportSettingsPopup = ({ { + processFromDate(date); + onDatePickerClose(); + }} + onSubmitCallback={processFromDate} label={t('startDate')} minDate={minDate} data-testid={`${dataTestId}-from-date`} @@ -157,7 +163,8 @@ export const ExportSettingsPopup = ({ Date: Sun, 13 Jul 2025 13:52:38 -0600 Subject: [PATCH 02/14] feat: Improve date correlation handling for datepickers Remove non-required onSubmit handler --- .../ExportSettingsPopup/ExportSettingsPopup.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx index 9acbefd756..28aadb953f 100644 --- a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx +++ b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx @@ -67,10 +67,15 @@ export const ExportSettingsPopup = ({ setValue('toDate', endOfDay(date)); }; - const onDatePickerClose = () => { + const onFromDatePickerClose = () => { + let newToDate = toDate; if (toDate < fromDate) { - setValue('toDate', addDays(fromDate, 1)); + const increasedFromDate = addDays(fromDate, 1); + const maxDate = getMaxDate(); + + newToDate = increasedFromDate <= maxDate ? increasedFromDate : maxDate; } + processToDate(newToDate); }; const onDateTypeChange = (e: SelectEvent) => { @@ -149,9 +154,8 @@ export const ExportSettingsPopup = ({ name="fromDate" onCloseCallback={(date) => { processFromDate(date); - onDatePickerClose(); + onFromDatePickerClose(); }} - onSubmitCallback={processFromDate} label={t('startDate')} minDate={minDate} data-testid={`${dataTestId}-from-date`} @@ -164,7 +168,6 @@ export const ExportSettingsPopup = ({ {...commonProps} name="toDate" onCloseCallback={processToDate} - onSubmitCallback={processToDate} minDate={fromDate} label={t('endDate')} data-testid={`${dataTestId}-to-date`} From 42697227b865f23f22cd140132af3bc958eb8ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Vital?= Date: Wed, 23 Jul 2025 13:47:46 -0600 Subject: [PATCH 03/14] feat: Update getMaxDate to be static prop --- .../ExportDataSetting/ExportDataSetting.tsx | 18 +++++++++--------- .../ExportSettingsPopup.test.tsx | 2 +- .../ExportSettingsPopup.tsx | 4 ++-- .../ExportSettingsPopup.types.ts | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/shared/features/AppletSettings/ExportDataSetting/ExportDataSetting.tsx b/src/shared/features/AppletSettings/ExportDataSetting/ExportDataSetting.tsx index 1fde85d87e..ba5307029b 100644 --- a/src/shared/features/AppletSettings/ExportDataSetting/ExportDataSetting.tsx +++ b/src/shared/features/AppletSettings/ExportDataSetting/ExportDataSetting.tsx @@ -1,15 +1,16 @@ +import { yupResolver } from '@hookform/resolvers/yup'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { ObjectSchema } from 'yup'; -import { yupResolver } from '@hookform/resolvers/yup'; import { DataExportPopup } from 'shared/features/AppletSettings/ExportDataSetting/Popups/DataExportPopup'; -import { applet } from 'shared/state/Applet'; -import { getNormalizedTimezoneDate } from 'shared/utils/dateTimezone'; -import { UniqueTuple } from 'shared/types'; import { useFeatureFlags } from 'shared/hooks'; import { FeatureFlagDefaults } from 'shared/hooks/useFeatureFlags.const'; +import { applet } from 'shared/state/Applet'; +import { UniqueTuple } from 'shared/types'; +import { getNormalizedTimezoneDate } from 'shared/utils/dateTimezone'; +import { exportDataSettingSchema } from './ExportDataSetting.schema'; import { ExportDataExported, ExportDataFormValues, @@ -18,7 +19,6 @@ import { SupplementaryFiles, SupplementaryFilesWithFeatureFlag, } from './ExportDataSetting.types'; -import { exportDataSettingSchema } from './ExportDataSetting.schema'; import { ExportSettingsPopup } from './Popups/ExportSettingsPopup/ExportSettingsPopup'; export const ExportDataSetting = ({ @@ -39,7 +39,7 @@ export const ExportDataSetting = ({ const canExportEhrHealthData = featureFlags.enableEhrHealthData !== 'unavailable'; const minDate = useMemo(() => new Date(appletData?.createdAt ?? ''), [appletData]); - const getMaxDate = () => getNormalizedTimezoneDate(new Date().toString()); + const maxDate = useMemo(() => getNormalizedTimezoneDate(new Date().toString()), []); const defaultValues: ExportDataFormValues = useMemo( () => ({ dataExported: canExportEhrHealthData @@ -47,13 +47,13 @@ export const ExportDataSetting = ({ : ExportDataExported.ResponsesOnly, dateType: ExportDateType.AllTime, fromDate: minDate, - toDate: getMaxDate(), + toDate: maxDate, supplementaryFiles: SupplementaryFiles.reduce( (acc, fileType) => ({ ...acc, [fileType]: false }), {} as Record, ), }), - [minDate, canExportEhrHealthData], + [minDate, maxDate, canExportEhrHealthData], ); const methods = useForm({ resolver: yupResolver(exportDataSettingSchema() as ObjectSchema), @@ -117,7 +117,7 @@ export const ExportDataSetting = ({ onExportSettingsClose(); }} minDate={minDate} - getMaxDate={getMaxDate} + maxDate={maxDate} appletName={appletName} supportedSupplementaryFiles={filteredSupportedSupplementaryFiles} canExportEhrHealthData={canExportEhrHealthData} diff --git a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.test.tsx b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.test.tsx index 63a2f2550d..6c2fb9244c 100644 --- a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.test.tsx +++ b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.test.tsx @@ -61,7 +61,7 @@ const commonProps = { onClose: mockOnClose, onExport: mockOnExport, minDate: date, - getMaxDate: () => getNormalizedTimezoneDate(new Date().toString()), + maxDate: getNormalizedTimezoneDate(new Date().toString()), appletName: mockedApplet.displayName, 'data-testid': DATA_TESTID_EXPORT_DATA_SETTINGS_POPUP, }; diff --git a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx index 28aadb953f..e0d8938b68 100644 --- a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx +++ b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx @@ -32,7 +32,7 @@ export const ExportSettingsPopup = ({ onClose, onExport, minDate, - getMaxDate, + maxDate, appletName, supportedSupplementaryFiles, canExportEhrHealthData, @@ -48,7 +48,7 @@ export const ExportSettingsPopup = ({ const hasCustomDate = dateType === ExportDateType.ChooseDates; const commonProps = { - maxDate: getMaxDate(), + maxDate, control, inputSx: { '& .MuiInputLabel-outlined': { diff --git a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.types.ts b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.types.ts index 144e6c2447..ac5da25c31 100644 --- a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.types.ts +++ b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.types.ts @@ -5,7 +5,7 @@ export type ExportSettingsPopupProps = { onClose: () => void; onExport: () => void; minDate: Date; - getMaxDate: () => Date; + maxDate: Date; appletName: string; supportedSupplementaryFiles?: SupplementaryFiles[]; canExportEhrHealthData?: boolean; From 52b13358f2b0740f569f53b8c2d544b8eafc270b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Vital?= Date: Wed, 23 Jul 2025 13:48:31 -0600 Subject: [PATCH 04/14] feat: Update min/max date normalizing for all types --- .../ExportSettingsPopup.tsx | 57 +++++++++---------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx index e0d8938b68..f272e36f08 100644 --- a/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx +++ b/src/shared/features/AppletSettings/ExportDataSetting/Popups/ExportSettingsPopup/ExportSettingsPopup.tsx @@ -1,6 +1,6 @@ import { Button } from '@mui/material'; import { addDays, endOfDay, startOfDay } from 'date-fns'; -import { useMemo } from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; import { useFormContext } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; @@ -17,7 +17,6 @@ import { StyledModalWrapper, theme, } from 'shared/styles'; -import { SelectEvent } from 'shared/types'; import { ExportDataFormValues, @@ -57,53 +56,56 @@ export const ExportSettingsPopup = ({ }, }; - const processFromDate = (date: DateType | undefined) => { - if (!date) return; - setValue('fromDate', startOfDay(date)); - }; + const processFromDate = useCallback( + (date: DateType | undefined) => { + if (!date) return; + setValue('fromDate', startOfDay(date)); + }, + [setValue], + ); - const processToDate = (date: DateType | undefined) => { - if (!date) return; - setValue('toDate', endOfDay(date)); - }; + const processToDate = useCallback( + (date: DateType | undefined) => { + if (!date) return; + setValue('toDate', endOfDay(date)); + }, + [setValue], + ); const onFromDatePickerClose = () => { let newToDate = toDate; if (toDate < fromDate) { const increasedFromDate = addDays(fromDate, 1); - const maxDate = getMaxDate(); newToDate = increasedFromDate <= maxDate ? increasedFromDate : maxDate; } processToDate(newToDate); }; - const onDateTypeChange = (e: SelectEvent) => { - const dateType = e.target.value as ExportDateType; - const maxDate = getMaxDate(); + useEffect(() => { switch (dateType) { case ExportDateType.AllTime: - setValue('fromDate', minDate); - setValue('toDate', maxDate); + processFromDate(minDate); + processToDate(maxDate); break; case ExportDateType.Last24h: setValue('fromDate', addDays(maxDate, -1)); setValue('toDate', maxDate); break; case ExportDateType.LastWeek: - setValue('fromDate', addDays(maxDate, -7)); - setValue('toDate', maxDate); + processFromDate(addDays(maxDate, -7)); + processToDate(maxDate); break; case ExportDateType.LastMonth: - setValue('fromDate', addDays(maxDate, -30)); - setValue('toDate', maxDate); + processFromDate(addDays(maxDate, -30)); + processToDate(maxDate); break; case ExportDateType.ChooseDates: - setValue('fromDate', minDate); - setValue('toDate', maxDate); + processFromDate(minDate); + processToDate(maxDate); break; } - }; + }, [dateType, minDate, maxDate, processFromDate, processToDate, setValue]); const filteredSupplementaryFiles = useMemo( () => @@ -143,7 +145,6 @@ export const ExportSettingsPopup = ({ options={getDateTypeOptions()} label={t('dateRange')} data-testid={`${dataTestId}-dateType`} - customChange={onDateTypeChange} fullWidth /> @@ -197,13 +198,7 @@ export const ExportSettingsPopup = ({ )}