diff --git a/.changeset/eighty-dryers-itch.md b/.changeset/eighty-dryers-itch.md new file mode 100644 index 00000000000..6deaa92ae0a --- /dev/null +++ b/.changeset/eighty-dryers-itch.md @@ -0,0 +1,5 @@ +--- +'@talend/react-components': patch +--- + +fix InputDateTimeRangePicker gets wrong error message for multiple errors diff --git a/packages/components/src/DateTimePickers/DateTimeRange/Manager/Manager.component.js b/packages/components/src/DateTimePickers/DateTimeRange/Manager/Manager.component.js index cc3a3750587..aeecc236825 100644 --- a/packages/components/src/DateTimePickers/DateTimeRange/Manager/Manager.component.js +++ b/packages/components/src/DateTimePickers/DateTimeRange/Manager/Manager.component.js @@ -19,6 +19,8 @@ function DateTimeRangeManager(props) { endDateTime, }; const [state, setState] = useState(initialState); + const [startDateErrors, setStartDateErrors] = useState([]); + const [endDateErrors, setEndDateErrors] = useState([]); useEffect(() => { if (!isEqual(state.startDateTime, startDateTime) || !isEqual(state.endDateTime, endDateTime)) { @@ -29,7 +31,12 @@ function DateTimeRangeManager(props) { function onRangeChange(event, nextState, origin) { const errors = [...(nextState.errors || [])]; - if (nextState.startDateTime && nextState.endDateTime) { + if ( + nextState.startDateTime && + nextState.endDateTime && + !isNaN(nextState.startDateTime) && + !isNaN(nextState.endDateTime) + ) { if (!isBefore(nextState.startDateTime, nextState.endDateTime)) { errors.push( new DateTimeRangePickerException( @@ -49,13 +56,17 @@ function DateTimeRangeManager(props) { } function onStartChange(event, { datetime, errors }) { - const nextState = { ...state, startDateTime: datetime, errors }; + setStartDateErrors(errors); + const allErrors = [...(errors || []), ...(endDateErrors || [])]; + const nextState = { ...state, startDateTime: datetime, errors: allErrors }; setState(nextState); onRangeChange(event, nextState, 'RANGE_START'); } function onEndChange(event, { datetime, errors }) { - const nextState = { ...state, endDateTime: datetime, errors }; + setEndDateErrors(errors); + const allErrors = [...(startDateErrors || []), ...(errors || [])]; + const nextState = { ...state, endDateTime: datetime, errors: allErrors }; setState(nextState); onRangeChange(event, nextState, 'RANGE_END'); } diff --git a/packages/components/src/DateTimePickers/InputDateTimeRangePicker/InputDateTimeRangePicker.component.test.js b/packages/components/src/DateTimePickers/InputDateTimeRangePicker/InputDateTimeRangePicker.component.test.js index 191a7a349bc..62a5e71d0da 100644 --- a/packages/components/src/DateTimePickers/InputDateTimeRangePicker/InputDateTimeRangePicker.component.test.js +++ b/packages/components/src/DateTimePickers/InputDateTimeRangePicker/InputDateTimeRangePicker.component.test.js @@ -1,4 +1,4 @@ -import { render, screen, within } from '@testing-library/react'; +import { fireEvent, render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import InputDateTimeRangePicker from './InputDateTimeRangePicker.component'; @@ -75,4 +75,54 @@ describe('InputDateTimeRangePicker', () => { new Date(new Date(today.getFullYear(), today.getMonth(), 13, 10, 0, 0)), ); }); + it('should show correct error message', async () => { + const TIME_ERROR = 'Time is required'; + const DATE_ERROR = 'Date is required'; + const user = userEvent.setup(); + + // GIVEN render with a default start time and end time + const onChange = jest.fn(); + render( + , + ); + const start = screen.getByTestId('range-start'); + const end = screen.getByTestId('range-end'); + + // WHEN remove the date from end time + const endDateControl = within(end).getByTestId('date-picker'); + await user.click(endDateControl); + await user.clear(endDateControl); + fireEvent.blur(endDateControl); + // THEN should get missing date error for end date + const payload0 = onChange.mock.calls[0][1]; + expect(payload0.errors.length).toBe(1); + expect(payload0.errorMessage).toBe(DATE_ERROR); + + // WHEN remove the time from start time + const startTimeControl = within(start).getByTestId('time-picker'); + await user.click(startTimeControl); + await user.clear(startTimeControl); + fireEvent.blur(startTimeControl); + // THEN should get missing time error for start time + const payload1 = onChange.mock.calls[1][1]; + expect(payload1.errors.length).toBe(2); + expect(payload1.errors[0].message).toBe(TIME_ERROR); + expect(payload1.errors[1].message).toBe(DATE_ERROR); + expect(payload1.errorMessage).toBe(TIME_ERROR); + + // WHEN input valid time for start time + await user.click(startTimeControl); + await user.type(startTimeControl, '08:20:10'); + fireEvent.blur(startTimeControl); + // THEN should get the remaining date error + const payload2 = onChange.mock.calls[2][1]; + expect(payload2.errors.length).toBe(1); + expect(payload2.errorMessage).toBe(DATE_ERROR); + }); });