Skip to content

Commit c091283

Browse files
Merge pull request Expensify#87079 from Expensify/claude-fixDateFilterResetPersistence
Fix date filter reset not persisting cleared values to Onyx
2 parents 66b119e + 6a96bd7 commit c091283

4 files changed

Lines changed: 98 additions & 7 deletions

File tree

src/components/Search/FilterComponents/DateFilterBase.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ type DateFilterBaseProps = {
3535
onBackButtonPress?: () => void;
3636
/** Callback when the filter is submitted with the selected date values */
3737
onSubmit: (values: SearchDateValues) => void;
38+
/** Callback when the filter is reset, used to persist cleared values without triggering navigation */
39+
onReset?: (values: SearchDateValues) => void;
3840
/** Callback when a date value changes (e.g. preset click or calendar save) */
3941
onDateValuesChange?: (values: SearchDateValues) => void;
4042
/** Controlled selected date modifier */
@@ -59,6 +61,7 @@ function DateFilterBase({
5961
isSearchAdvancedFiltersFormLoading,
6062
onBackButtonPress,
6163
onSubmit,
64+
onReset,
6265
onDateValuesChange,
6366
onDateModifierChange,
6467
shouldShowButtonsOnlyWithDateModifier = false,
@@ -157,15 +160,19 @@ function DateFilterBase({
157160

158161
if (selectedDateModifier) {
159162
searchDatePresetFilterBaseRef.current.clearDateValueOfSelectedDateModifier();
163+
const dateValues = searchDatePresetFilterBaseRef.current.getDateValues();
160164
setSelectedDateModifier(null);
161165
setShouldShowRangeError(false);
162166
onDateModifierChange?.(false);
167+
onReset?.(dateValues);
163168
return;
164169
}
165170

166171
searchDatePresetFilterBaseRef.current.clearDateValues();
172+
const dateValues = searchDatePresetFilterBaseRef.current.getDateValues();
167173
setShouldShowRangeError(false);
168-
}, [onDateModifierChange, selectedDateModifier, setSelectedDateModifier]);
174+
onReset?.(dateValues);
175+
}, [onDateModifierChange, onReset, selectedDateModifier, setSelectedDateModifier]);
169176

170177
const save = useCallback(() => {
171178
if (!searchDatePresetFilterBaseRef.current) {
@@ -231,12 +238,14 @@ function DateFilterBase({
231238
)}
232239
{shouldShowActionButtons && (
233240
<>
234-
<Button
235-
text={translate('common.reset')}
236-
onPress={reset}
237-
style={[styles.mh4, styles.mt4]}
238-
large
239-
/>
241+
{!selectedDateModifier && (
242+
<Button
243+
text={translate('common.reset')}
244+
onPress={reset}
245+
style={[styles.mh4, styles.mt4]}
246+
large
247+
/>
248+
)}
240249
<FormAlertWithSubmitButton
241250
buttonText={translate('common.save')}
242251
containerStyles={[styles.m4, styles.mt3, styles.mb5]}

src/components/Search/SearchDatePresetFilterBasePage.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ function SearchDatePresetFilterBasePage({dateKey, titleKey}: SearchDatePresetFil
139139
});
140140
Navigation.goBack(ROUTES.SEARCH_ADVANCED_FILTERS.getRoute());
141141
}}
142+
onReset={(values) => {
143+
updateAdvancedFilters({
144+
[dateOnKey]: values[CONST.SEARCH.DATE_MODIFIERS.ON] ?? null,
145+
[dateBeforeKey]: values[CONST.SEARCH.DATE_MODIFIERS.BEFORE] ?? null,
146+
[dateAfterKey]: values[CONST.SEARCH.DATE_MODIFIERS.AFTER] ?? null,
147+
[dateRangeKey]: values[CONST.SEARCH.DATE_MODIFIERS.RANGE] ?? null,
148+
});
149+
}}
142150
/>
143151
</ScreenWrapper>
144152
);

src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersReportFieldPage/ReportFieldDate.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ function ReportFieldDate({field, close}: ReportFieldDateProps) {
6868
isSearchAdvancedFiltersFormLoading={isSearchAdvancedFiltersFormLoading}
6969
onBackButtonPress={close}
7070
onSubmit={updateFilter}
71+
onReset={(values) => {
72+
updateAdvancedFilters({
73+
[dateOnKey]: values[CONST.SEARCH.DATE_MODIFIERS.ON] ?? null,
74+
[dateBeforeKey]: values[CONST.SEARCH.DATE_MODIFIERS.BEFORE] ?? null,
75+
[dateAfterKey]: values[CONST.SEARCH.DATE_MODIFIERS.AFTER] ?? null,
76+
[dateRangeKey]: values[CONST.SEARCH.DATE_MODIFIERS.RANGE] ?? null,
77+
});
78+
}}
7179
/>
7280
);
7381
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import {fireEvent, render, screen} from '@testing-library/react-native';
2+
import React from 'react';
3+
import Onyx from 'react-native-onyx';
4+
import ComposeProviders from '@components/ComposeProviders';
5+
import {LocaleContextProvider} from '@components/LocaleContextProvider';
6+
import OnyxListItemProvider from '@components/OnyxListItemProvider';
7+
import DateFilterBase from '@components/Search/FilterComponents/DateFilterBase';
8+
import type {SearchDateValues} from '@components/Search/FilterComponents/DatePresetFilterBase';
9+
import CONST from '@src/CONST';
10+
import ONYXKEYS from '@src/ONYXKEYS';
11+
12+
jest.mock('@components/ConfirmedRoute.tsx');
13+
jest.mock('@libs/Navigation/Navigation');
14+
15+
const defaultDateValues: SearchDateValues = {
16+
[CONST.SEARCH.DATE_MODIFIERS.ON]: '2025-01-15',
17+
[CONST.SEARCH.DATE_MODIFIERS.BEFORE]: undefined,
18+
[CONST.SEARCH.DATE_MODIFIERS.AFTER]: undefined,
19+
[CONST.SEARCH.DATE_MODIFIERS.RANGE]: undefined,
20+
};
21+
22+
const emptyDateValues: SearchDateValues = {
23+
[CONST.SEARCH.DATE_MODIFIERS.ON]: undefined,
24+
[CONST.SEARCH.DATE_MODIFIERS.BEFORE]: undefined,
25+
[CONST.SEARCH.DATE_MODIFIERS.AFTER]: undefined,
26+
[CONST.SEARCH.DATE_MODIFIERS.RANGE]: undefined,
27+
};
28+
29+
function renderDateFilterBase(props: {onSubmit?: jest.Mock; onReset?: jest.Mock; defaultDateValues?: SearchDateValues}) {
30+
return render(
31+
<ComposeProviders components={[OnyxListItemProvider, LocaleContextProvider]}>
32+
<DateFilterBase
33+
title="Date"
34+
defaultDateValues={props.defaultDateValues ?? defaultDateValues}
35+
presets={[]}
36+
onSubmit={props.onSubmit ?? jest.fn()}
37+
onReset={props.onReset}
38+
/>
39+
</ComposeProviders>,
40+
);
41+
}
42+
43+
describe('DateFilterBase reset', () => {
44+
beforeAll(() =>
45+
Onyx.init({
46+
keys: ONYXKEYS,
47+
evictableKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS],
48+
}),
49+
);
50+
51+
afterEach(async () => {
52+
await Onyx.clear();
53+
jest.clearAllMocks();
54+
});
55+
56+
it('calls onReset with cleared date values when reset is pressed', () => {
57+
const onReset = jest.fn();
58+
renderDateFilterBase({onReset});
59+
60+
const resetButton = screen.getByText(/^(Reset|common\.reset)$/);
61+
fireEvent.press(resetButton);
62+
63+
expect(onReset).toHaveBeenCalledTimes(1);
64+
expect(onReset).toHaveBeenCalledWith(emptyDateValues);
65+
});
66+
});

0 commit comments

Comments
 (0)