Skip to content

Commit

Permalink
STSMACOM-838 Implement prop for DateRangeFilter to allow for open-e…
Browse files Browse the repository at this point in the history
…nded ranges. (#1495)

* provide requiredFields prop on Daterange filter for variable validation of fields

* log changes

* account for both dates missing
  • Loading branch information
JohnC-80 authored Jul 30, 2024
1 parent 2ac6fac commit 134d9ef
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Add an optional `isCursorAtEnd` property for `SearchField`. Pass `resetSelectedItem` to `onDismissDetail`. STSMACOM-841.
* Add check for the error status when error occurs during adding tag. STSMACOM-844.
* Add optional `isRequestUrlExceededLimit` property to `<SearchAndSort>` to return a specific error message in `StripesConnectedSource`. Refs STSMACOM-846.
* Add `requiredFields` prop to `DateRangeFilter` to support open-ended date ranges. STSMACOM-838.

## [9.1.1] (IN PROGRESS)

Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export { default as CollapseFilterPaneButton } from './lib/SearchAndSort/compone
export { default as MultiSelectionFilter } from './lib/SearchAndSort/components/MultiSelectionFilter';

export { default as DateRangeFilter } from './lib/SearchAndSort/components/DateRangeFilter';
export { default as DATE_TYPES } from './lib/SearchAndSort/components/DateRangeFilter/date-types';

export { default as makeQueryFunction } from './lib/SearchAndSort/makeQueryFunction';
export { default as advancedSearchQueryToRows } from './lib/SearchAndSort/advancedSearchQueryToRows';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const TheComponent = ({
makeFilterString,
onChange,
focusRef,
requiredFields = [DATE_TYPES.START, DATE_TYPES.END],
}) => {
const [filterValue, setFilterValue] = React.useState({
...defaultFilterState,
Expand Down Expand Up @@ -125,7 +126,7 @@ const TheComponent = ({
const bothDatesEmpty = startDate === '' && endDate === '';

if (!bothDatesEmpty) {
const validationData = validateDateRange(selectedValuesState, dateFormat);
const validationData = validateDateRange(selectedValuesState, dateFormat, requiredFields);

setFilterValue(prevState => ({
...prevState,
Expand All @@ -134,7 +135,7 @@ const TheComponent = ({

if (validationData.dateRangeValid) applyFilter();
}
}, [applyFilter, dateFormat, endDate, selectedValuesState, startDate]);
}, [applyFilter, dateFormat, endDate, selectedValuesState, startDate, requiredFields]);

const handleDateChange = (event, field) => {
const date = event.target.value;
Expand Down Expand Up @@ -224,6 +225,7 @@ TheComponent.propTypes = {
endDate: PropTypes.string.isRequired,
startDate: PropTypes.string.isRequired,
}).isRequired,
requiredFields: PropTypes.arrayOf(PropTypes.oneOf([DATE_TYPES.START, DATE_TYPES.END])),
};

const DateRangeFilter = memo(TheComponent, arePropsEqual);
Expand Down
39 changes: 28 additions & 11 deletions lib/SearchAndSort/components/DateRangeFilter/date-validations.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import moment from 'moment';
import DATE_TYPES from './date-types';

export const isDateValid = (date, dateFormat) => {
const momentDateWrapper = moment(date, dateFormat, true);

return momentDateWrapper.isValid();
};

export const validateDateRange = (dateRange, dateFormat) => {
export const validateDateRange = (dateRange, dateFormat, requiredFields = [DATE_TYPES.START, DATE_TYPES.END]) => {
const {
startDate,
endDate,
Expand All @@ -18,16 +19,32 @@ export const validateDateRange = (dateRange, dateFormat) => {
const startDateEmpty = startDate === '';
const endDateEmpty = endDate === '';
const bothDatesEntered = !startDateEmpty && !endDateEmpty;
const startDateMissing = !bothDatesEntered && !endDateEmpty;
const endDateMissing = !bothDatesEntered && !startDateEmpty;

const startDateInvalid = !startDateEmpty && !isDateValid(startDate, dateFormat);
const endDateInvalid = !endDateEmpty && !isDateValid(endDate, dateFormat);
const bothDatesValid = !startDateInvalid && !endDateInvalid;

const wrongDatesOrder = bothDatesValid && startDateMomentWrapper.isAfter(endDateMomentWrapper);

const dateRangeValid = bothDatesEntered && bothDatesValid && !wrongDatesOrder;
let startDateMissing = !bothDatesEntered && !endDateEmpty;
let endDateMissing = !bothDatesEntered && !startDateEmpty;

let startDateInvalid = !isDateValid(startDate, dateFormat);
let endDateInvalid = !isDateValid(endDate, dateFormat);

let dateRangeValid = false;
let wrongDatesOrder = false;
if (bothDatesEntered) {
const bothDatesValid = !startDateInvalid && !endDateInvalid;
wrongDatesOrder = bothDatesValid && startDateMomentWrapper.isAfter(endDateMomentWrapper);
dateRangeValid = bothDatesEntered && bothDatesValid && !wrongDatesOrder;
} else if (startDateEmpty && endDateEmpty) {
startDateMissing = requiredFields.includes(DATE_TYPES.START);
endDateMissing = requiredFields.includes(DATE_TYPES.END);
startDateInvalid = false;
endDateInvalid = false;
} else if (startDateEmpty) {
startDateMissing = requiredFields.includes(DATE_TYPES.START);
startDateInvalid = false;
dateRangeValid = !startDateMissing && !endDateInvalid;
} else if (endDateEmpty) {
endDateMissing = requiredFields.includes(DATE_TYPES.END);
endDateInvalid = false;
dateRangeValid = !endDateMissing && !startDateInvalid;
}

return {
dateRangeValid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { setupApplication, mount } from '../../../../../tests/helpers';

import DateRangeFilter from '../DateRangeFilter';
import DateRangeFilterInteractor from './interactor';
import { validateDateRange } from '../date-validations';
import DATE_TYPES from '../date-types';

const dateRangeFilter = new DateRangeFilterInteractor();

Expand Down Expand Up @@ -271,3 +273,194 @@ describe('DateRangeFilter', () => {
});
});
});

describe('Validate date range', () => {
it('both dates present', () => {
expect(validateDateRange(
{
startDate: '2020-06-13',
endDate:'2021-01-20'
}, 'YYYY-MM-DD'
)).to.deep.equal({
dateRangeValid: true,
errors: {
startDateInvalid: false,
endDateInvalid: false,
endDateMissing: false,
startDateMissing: false,
wrongDatesOrder: false,
}
});
});

it('both dates present - start invalid', () => {
expect(validateDateRange(
{
startDate: '2025513',
endDate:'2021-01-20'
}, 'YYYY-MM-DD'
)).to.deep.equal({
dateRangeValid: false,
errors: {
startDateInvalid: true,
endDateInvalid: false,
endDateMissing: false,
startDateMissing: false,
wrongDatesOrder: false,
}
});
});

it('both dates present - end invalid', () => {
expect(validateDateRange(
{
startDate: '2020-06-13',
endDate:'20215520'
}, 'YYYY-MM-DD'
)).to.deep.equal({
dateRangeValid: false,
errors: {
startDateInvalid: false,
endDateInvalid: true,
endDateMissing: false,
startDateMissing: false,
wrongDatesOrder: false,
}
});
});

it('start date missing, both required', () => {
expect(validateDateRange(
{
startDate: '',
endDate:'2021-01-20'
}, 'YYYY-MM-DD'
)).to.deep.equal({
dateRangeValid: false,
errors: {
startDateInvalid: false,
endDateInvalid: false,
endDateMissing: false,
startDateMissing: true,
wrongDatesOrder: false,
}
});
});

it('start date missing, both not required', () => {
expect(validateDateRange(
{
startDate: '',
endDate:'2021-01-20'
},
'YYYY-MM-DD',
[],
)).to.deep.equal({
dateRangeValid: true,
errors: {
startDateInvalid: false,
endDateInvalid: false,
endDateMissing: false,
startDateMissing: false,
wrongDatesOrder: false,
}
});
});

it('start date missing, start date required', () => {
expect(validateDateRange(
{
startDate: '',
endDate:'2021-01-20'
},
'YYYY-MM-DD',
[DATE_TYPES.START],
)).to.deep.equal({
dateRangeValid: false,
errors: {
startDateInvalid: false,
endDateInvalid: false,
endDateMissing: false,
startDateMissing: true,
wrongDatesOrder: false,
}
});
});

it('end date missing', () => {
expect(validateDateRange(
{
startDate: '2020-06-13',
endDate:''
}, 'YYYY-MM-DD'
)).to.deep.equal({
dateRangeValid: false,
errors: {
startDateInvalid: false,
endDateInvalid: false,
endDateMissing: true,
startDateMissing: false,
wrongDatesOrder: false,
}
});
});

it('end date missing, both not required', () => {
expect(validateDateRange(
{
startDate: '2020-06-13',
endDate:''
},
'YYYY-MM-DD',
[]
)).to.deep.equal({
dateRangeValid: true,
errors: {
startDateInvalid: false,
endDateInvalid: false,
endDateMissing: false,
startDateMissing: false,
wrongDatesOrder: false,
}
});
});

it('end date missing, end not required', () => {
expect(validateDateRange(
{
startDate: '2020-06-13',
endDate:''
},
'YYYY-MM-DD',
[DATE_TYPES.START]
)).to.deep.equal({
dateRangeValid: true,
errors: {
startDateInvalid: false,
endDateInvalid: false,
endDateMissing: false,
startDateMissing: false,
wrongDatesOrder: false,
}
});
});

it('both dates missing, both required', () => {
expect(validateDateRange(
{
startDate: '',
endDate:''
},
'YYYY-MM-DD',
)).to.deep.equal({
dateRangeValid: false,
errors: {
startDateInvalid: false,
endDateInvalid: false,
endDateMissing: true,
startDateMissing: true,
wrongDatesOrder: false,
}
});
});
});

0 comments on commit 134d9ef

Please sign in to comment.