Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(LastSeenFilter): Fixes Validators and adds test #1837

Merged
merged 1 commit into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"html-webpack-plugin": "^5.5.0",
"lodash": "^4.17.21",
"marked": "^4.0.10",
"moment": "^2.29.4",
"p-all": "^4.0.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
Expand Down
6 changes: 4 additions & 2 deletions src/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,10 @@ export async function getEntities(items, {
...(options.filter && Object.keys(options.filter).length && generateFilter(options.filter)),
...(calculateSystemProfile(filters)),
...(fields && Object.keys(fields).length && generateFilter(fields, 'fields')),
...filters?.lastSeenFilter?.updatedStart && { updated_start: filters.lastSeenFilter.updatedStart },
...filters?.lastSeenFilter?.updatedEnd && { updated_end: filters.lastSeenFilter.updatedEnd }
...filters?.lastSeenFilter?.updatedStart &&
filters?.lastSeenFilter?.updatedStart.length > 0 && { updated_start: filters.lastSeenFilter.updatedStart },
...filters?.lastSeenFilter?.updatedEnd &&
filters?.lastSeenFilter?.updatedEnd.length > 0 && { updated_end: filters.lastSeenFilter.updatedEnd }
}
}
)
Expand Down
12 changes: 8 additions & 4 deletions src/components/InventoryTable/EntityTableToolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import useOperatingSystemFilter from '../filters/useOperatingSystemFilter';
import useFeatureFlag from '../../Utilities/useFeatureFlag';
import useGroupFilter from '../filters/useGroupFilter';
import { DatePicker, Split, SplitItem } from '@patternfly/react-core';
import { fromValidator, toValidator } from '../filters/helpers';

/**
* Table toolbar used at top of inventory table.
Expand Down Expand Up @@ -112,7 +113,7 @@ const EntityTableToolbar = ({
const [registeredFilter, registeredChip, registeredWithFilter, setRegisteredWithFilter] = useRegisteredWithFilter(reducer);
const [rhcdFilterConfig, rhcdFilterChips, rhcdFilterValue, setRhcdFilterValue] = useRhcdFilter(reducer);
const [lastSeenFilter, lastSeenChip, lastSeenFilterValue, setLastSeenFilterValue,
toValidator, onFromChange, onToChange, endDate, startDate, fromValidator,
onFromChange, onToChange, endDate, startDate,
setStartDate, setEndDate] = useLastSeenFilter(reducer);
const [osFilterConfig, osFilterChips, osFilterValue, setOsFilterValue] = useOperatingSystemFilter();
const [updateMethodConfig, updateMethodChips, updateMethodValue, setUpdateMethodValue] = useUpdateMethodFilter(reducer);
Expand Down Expand Up @@ -348,6 +349,8 @@ const EntityTableToolbar = ({
enabledFilters.lastSeenFilter && setLastSeenFilterValue([]);
enabledFilters.updateMethodFilter && setUpdateMethodValue([]);
enabledFilters.hostGroupFilter && setHostGroupValue([]);
setEndDate();
setStartDate();
dispatch(setFilter([]));
updateData({ page: 1, filters: [] });
};
Expand Down Expand Up @@ -444,7 +447,7 @@ const EntityTableToolbar = ({
<DatePicker
onChange={onFromChange}
aria-label="Start date"
validators={[fromValidator]}
validators={[fromValidator(endDate)]}
placeholder='Start'
/>
</SplitItem>
Expand All @@ -455,8 +458,9 @@ const EntityTableToolbar = ({
<DatePicker
value={endDate}
onChange={onToChange}
rangeStart={startDate}
validators={[toValidator]}
rangeStart={new Date(startDate)
}
validators={[toValidator(startDate)]}
aria-label="End date"
placeholder='End'
/>
Expand Down
38 changes: 38 additions & 0 deletions src/components/filters/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import moment from 'moment';

export const oldestDate = new Date(1950, 1, 1);
//validators control what date ranges can be selected in the component.
//both validators need to keep in mind todays date, and the other components inputed date.

//maxDate is the other date pickers currently selected Date
//date is patternfly component date
export const fromValidator = (maxDate) => (date) => {
const todaysDate = moment().startOf('day');
const newMaxDate = moment(maxDate).startOf('day');

if (date < oldestDate) {
return 'Date is before the allowable range.';
} else if (date > newMaxDate) {
return `End date must be later than Start date.`;
} else if (date > todaysDate) {
return ' Start date must be earlier than End date.';
} else {
return '';
}
};

//minDate is the other components currently selected Date
//dateToValidate is patternfly component date.
export const toValidator = (minDate) => (dateToValidate) => {
const todaysDate = moment().endOf('day');
const newDatetoValidate = new Date(dateToValidate);
const newMinDate = moment(minDate).startOf('day');

if (newDatetoValidate < newMinDate) {
return 'Start date must be earlier than End date.';
} else if (newDatetoValidate > todaysDate) {
return `Date must be ${todaysDate.toISOString().split('T')[0]} or earlier`;
} else {
return '';
}
};
16 changes: 16 additions & 0 deletions src/components/filters/helpers.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { fromValidator, toValidator } from './helpers';
import moment from 'moment';

describe('Validates datepicker dates', () => {
it('ToValidator', () => {
const startOfToday = moment().startOf('day');
const endOfToday = moment().endOf('day');
expect(toValidator(startOfToday)(endOfToday)).toEqual('');
});
it('FromValidator', () => {
const startOfToday = moment().startOf('day');
const endOfToday = moment().endOf('day');
expect(fromValidator(endOfToday)(startOfToday)).toEqual('');

});
});
94 changes: 43 additions & 51 deletions src/components/filters/useLastSeenFilter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useState } from 'react';
import { LAST_SEEN_CHIP, lastSeenItems } from '../../Utilities/constants';

import moment from 'moment';
import { oldestDate } from './helpers.js';
export const lastSeenFilterState = { lastSeenFilter: [] };
export const LAST_SEEN_FILTER = 'LAST_SEEN_FILTER';
export const lastSeenFilterReducer = (_state, { type, payload }) => ({
Expand Down Expand Up @@ -42,81 +43,74 @@ export const useLastSeenFilter = (
]
: [];

const [startDate, setStartDate] = useState();
const [startDate, setStartDate] = useState(oldestDate);
const [endDate, setEndDate] = useState();
const todaysDate = new Date();
const todaysDate = moment();

const manageStartDate = (apiStartDate, apiEndDate)=> {
if (isNaN(apiEndDate) && isNaN(apiStartDate)) {
const manageStartDate = (apiStartDate, apiEndDate) => {
const newApiStartDate = apiStartDate;
const newApiEndDate = apiEndDate;
if (isNaN(newApiEndDate) && isNaN(newApiStartDate)) {
setValue({ ...lastSeenValue, updatedStart: null, updatedEnd: null });
} else if (apiStartDate > apiEndDate || isNaN(apiStartDate) || apiStartDate > todaysDate) {
setValue({ ...lastSeenValue, updatedStart: null, updatedEnd: apiEndDate.toISOString() });
} else {
setValue({ ...lastSeenValue, updatedStart: apiStartDate.toISOString() });
}
};

const manageEndDate = (apiStartDate, apiEndDate)=> {
if (isNaN(apiEndDate) && isNaN(apiStartDate)) {
setValue({ ...lastSeenValue, updatedStart: null, updatedEnd: null });
} else if (apiStartDate > apiEndDate || isNaN(apiEndDate)) {
setValue({ ...lastSeenValue, updatedStart: apiStartDate.toISOString(), updatedEnd: null });
} else {
setValue({ ...lastSeenValue, updatedEnd: apiEndDate.toISOString() });
}
};

const toValidator = (date) => {
const newDate = new Date(date);
const minDate = new Date(startDate);

if (minDate >= newDate) {
return 'Start date must be earlier than End date.';
} else if (newDate > todaysDate) {
return `Date must be ${todaysDate.toISOString().split('T')[0]} or earlier`;
} else if (
newApiStartDate > newApiEndDate ||
isNaN(newApiStartDate) ||
newApiStartDate > todaysDate
) {
setValue({
...lastSeenValue,
updatedStart: null,
updatedEnd: newApiEndDate
});
} else {
return '';
setValue({
...lastSeenValue,
updatedStart: `${newApiStartDate.format('YYYY-MM-DD')}T00:00:00.000Z`
});
}
};

const fromValidator = (date) => {
const minDate = new Date(1950, 1, 1);
const maxDate = new Date(endDate);
const manageEndDate = (apiStartDate, apiEndDate) => {
const newApiStartDate = apiStartDate.startOf('day');
const newApiEndDate = apiEndDate.endOf('day');

if (date < minDate) {
return 'Date is before the allowable range.';
} else if (date > maxDate) {
return `End date must be later than Start date.`;
} else if (date > todaysDate) {
return ' Start date must be earlier than End date.';
if (isNaN(newApiEndDate) && isNaN(newApiStartDate)) {
setValue({ ...lastSeenValue, updatedStart: null, updatedEnd: null });
} else if (newApiStartDate > newApiEndDate || isNaN(newApiEndDate)) {
setValue({
...lastSeenValue,
updatedStart: newApiStartDate,
updatedEnd: null
});
} else {
return '';
setValue({ ...lastSeenValue, updatedEnd: `${newApiEndDate.format('YYYY-MM-DD')}T23:59:00.000Z` });
}
};

//This date comes from patternfly component. This manages the 1st date picker
const onFromChange = (date) => {
const newToDate = new Date(endDate);
const newToDate = moment(endDate).endOf('day');
if (date > newToDate) {
setStartDate();
return 'End date must be later than Start date.';
}

setStartDate(date);
const apiStartDate = new Date(date);
apiStartDate.setUTCHours(0);
const apiStartDate = moment(date).startOf('day');

manageStartDate(apiStartDate, newToDate);
};

//This date comes from patternfly component. This manages the 2nd date picker
const onToChange = (date) => {
if (startDate > new Date(date)) {
if (startDate > moment(date)) {
return 'Start date must be earlier than End date.';
} else if (new Date(date) > todaysDate) {
} else if (moment(date) > todaysDate) {
return 'End date must be later than Start date.';
} else {
setEndDate(date);
const apiEndDate = new Date(date);
apiEndDate.setUTCHours(23, 59);
manageEndDate(new Date(startDate), apiEndDate);
const apiEndDate = moment(date).endOf('day');
manageEndDate(moment(startDate), apiEndDate);
}
};

Expand All @@ -125,12 +119,10 @@ export const useLastSeenFilter = (
chip,
lastSeenValue,
setValue,
toValidator,
onFromChange,
onToChange,
endDate,
startDate,
fromValidator,
setStartDate,
setEndDate
];
Expand Down