Skip to content
23 changes: 16 additions & 7 deletions src/components/Search/FilterComponents/DateFilterBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type DateFilterBaseProps = {
onBackButtonPress?: () => void;
/** Callback when the filter is submitted with the selected date values */
onSubmit: (values: SearchDateValues) => void;
/** Callback when the filter is reset, used to persist cleared values without triggering navigation */
onReset?: (values: SearchDateValues) => void;
/** Callback when a date value changes (e.g. preset click or calendar save) */
onDateValuesChange?: (values: SearchDateValues) => void;
/** Controlled selected date modifier */
Expand All @@ -59,6 +61,7 @@ function DateFilterBase({
isSearchAdvancedFiltersFormLoading,
onBackButtonPress,
onSubmit,
onReset,
onDateValuesChange,
onDateModifierChange,
shouldShowButtonsOnlyWithDateModifier = false,
Expand Down Expand Up @@ -157,15 +160,19 @@ function DateFilterBase({

if (selectedDateModifier) {
searchDatePresetFilterBaseRef.current.clearDateValueOfSelectedDateModifier();
const dateValues = searchDatePresetFilterBaseRef.current.getDateValues();
setSelectedDateModifier(null);
setShouldShowRangeError(false);
onDateModifierChange?.(false);
onReset?.(dateValues);
return;
}

searchDatePresetFilterBaseRef.current.clearDateValues();
const dateValues = searchDatePresetFilterBaseRef.current.getDateValues();
setShouldShowRangeError(false);
}, [onDateModifierChange, selectedDateModifier, setSelectedDateModifier]);
onReset?.(dateValues);
}, [onDateModifierChange, onReset, selectedDateModifier, setSelectedDateModifier]);

const save = useCallback(() => {
if (!searchDatePresetFilterBaseRef.current) {
Expand Down Expand Up @@ -231,12 +238,14 @@ function DateFilterBase({
)}
{shouldShowActionButtons && (
<>
<Button
text={translate('common.reset')}
onPress={reset}
style={[styles.mh4, styles.mt4]}
large
/>
{!selectedDateModifier && (
<Button
text={translate('common.reset')}
onPress={reset}
style={[styles.mh4, styles.mt4]}
large
/>
)}
<FormAlertWithSubmitButton
buttonText={translate('common.save')}
containerStyles={[styles.m4, styles.mt3, styles.mb5]}
Expand Down
8 changes: 8 additions & 0 deletions src/components/Search/SearchDatePresetFilterBasePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ function SearchDatePresetFilterBasePage({dateKey, titleKey}: SearchDatePresetFil
});
Navigation.goBack(ROUTES.SEARCH_ADVANCED_FILTERS.getRoute());
}}
onReset={(values) => {
updateAdvancedFilters({
[dateOnKey]: values[CONST.SEARCH.DATE_MODIFIERS.ON] ?? null,
[dateBeforeKey]: values[CONST.SEARCH.DATE_MODIFIERS.BEFORE] ?? null,
[dateAfterKey]: values[CONST.SEARCH.DATE_MODIFIERS.AFTER] ?? null,
[dateRangeKey]: values[CONST.SEARCH.DATE_MODIFIERS.RANGE] ?? null,
});
}}
/>
</ScreenWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ function ReportFieldDate({field, close}: ReportFieldDateProps) {
isSearchAdvancedFiltersFormLoading={isSearchAdvancedFiltersFormLoading}
onBackButtonPress={close}
onSubmit={updateFilter}
onReset={(values) => {
updateAdvancedFilters({
[dateOnKey]: values[CONST.SEARCH.DATE_MODIFIERS.ON] ?? null,
[dateBeforeKey]: values[CONST.SEARCH.DATE_MODIFIERS.BEFORE] ?? null,
[dateAfterKey]: values[CONST.SEARCH.DATE_MODIFIERS.AFTER] ?? null,
[dateRangeKey]: values[CONST.SEARCH.DATE_MODIFIERS.RANGE] ?? null,
});
}}
/>
);
}
Expand Down
66 changes: 66 additions & 0 deletions tests/ui/DateFilterBaseResetTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {fireEvent, render, screen} from '@testing-library/react-native';
import React from 'react';
import Onyx from 'react-native-onyx';
import ComposeProviders from '@components/ComposeProviders';
import {LocaleContextProvider} from '@components/LocaleContextProvider';
import OnyxListItemProvider from '@components/OnyxListItemProvider';
import DateFilterBase from '@components/Search/FilterComponents/DateFilterBase';
import type {SearchDateValues} from '@components/Search/FilterComponents/DatePresetFilterBase';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';

jest.mock('@components/ConfirmedRoute.tsx');
jest.mock('@libs/Navigation/Navigation');

const defaultDateValues: SearchDateValues = {
[CONST.SEARCH.DATE_MODIFIERS.ON]: '2025-01-15',
[CONST.SEARCH.DATE_MODIFIERS.BEFORE]: undefined,
[CONST.SEARCH.DATE_MODIFIERS.AFTER]: undefined,
[CONST.SEARCH.DATE_MODIFIERS.RANGE]: undefined,
};

const emptyDateValues: SearchDateValues = {
[CONST.SEARCH.DATE_MODIFIERS.ON]: undefined,
[CONST.SEARCH.DATE_MODIFIERS.BEFORE]: undefined,
[CONST.SEARCH.DATE_MODIFIERS.AFTER]: undefined,
[CONST.SEARCH.DATE_MODIFIERS.RANGE]: undefined,
};

function renderDateFilterBase(props: {onSubmit?: jest.Mock; onReset?: jest.Mock; defaultDateValues?: SearchDateValues}) {
return render(
<ComposeProviders components={[OnyxListItemProvider, LocaleContextProvider]}>
<DateFilterBase
title="Date"
defaultDateValues={props.defaultDateValues ?? defaultDateValues}
presets={[]}
onSubmit={props.onSubmit ?? jest.fn()}
onReset={props.onReset}
/>
</ComposeProviders>,
);
}

describe('DateFilterBase reset', () => {
beforeAll(() =>
Onyx.init({
keys: ONYXKEYS,
evictableKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS],
}),
);

afterEach(async () => {
await Onyx.clear();
jest.clearAllMocks();
});

it('calls onReset with cleared date values when reset is pressed', () => {
const onReset = jest.fn();
renderDateFilterBase({onReset});

const resetButton = screen.getByText(/^(Reset|common\.reset)$/);
fireEvent.press(resetButton);

expect(onReset).toHaveBeenCalledTimes(1);
expect(onReset).toHaveBeenCalledWith(emptyDateValues);
});
});
Loading