react-mapfilter
Version:
These components are designed for viewing data in Mapeo. They share a common interface:
126 lines (114 loc) • 4.01 kB
JavaScript
import "core-js/modules/es.array.iterator";
import "core-js/modules/web.dom-collections.iterator";
import _Array$isArray from "@babel/runtime-corejs3/core-js-stable/array/is-array";
import _findInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find";
// @flow
import * as React from 'react';
import DateIcon from '@material-ui/icons/DateRange';
import { makeStyles } from '@material-ui/core/styles';
import ListItem from '@material-ui/core/ListItem';
import { useIntl, defineMessages } from 'react-intl';
import { parseDateString } from '../utils/helpers';
import FilterSection from './FilterSection';
import DateField from '../ObservationDialog/DateField';
/*:: import type { Key, Filter } from '../types'*/
const m = defineMessages({
// Title of min date field in filter
min: {
"id": "BB/6+g==",
"defaultMessage": 'From'
},
// Title of max date field in filter
max: {
"id": "MOvYnQ==",
"defaultMessage": 'To'
}
});
/*:: type Props = {
label: React.Node,
fieldKey: Key,
filter?: Filter | null,
min: string,
max: string,
type?: 'date' | 'datetime',
onChangeFilter: (filter: Array<any> | null) => void
}*/
const DateFilter = ({
label,
fieldKey,
filter,
min,
max,
type = 'datetime',
onChangeFilter
}
/*: Props*/
) => {
const cx = useStyles();
const {
formatMessage: t
} = useIntl();
const [filterMin, filterMax] = parseDateFilter(filter);
const isFiltered = filterMin != null && filterMin > min || filterMax != null && filterMax < max;
const handleChange = (minOrMax
/*: 'min' | 'max'*/
) => value => {
const filterValue = createFilterValue(value, minOrMax);
const newFilter = minOrMax === 'min' ? compileFilter(fieldKey, filterValue, filterMax && (filterMax < filterValue ? createFilterValue(value, 'max') : filterMax)) : compileFilter(fieldKey, filterMin && (filterMin > filterValue ? createFilterValue(value, 'min') : filterMin), filterValue);
onChangeFilter(newFilter);
};
return /*#__PURE__*/React.createElement(FilterSection, {
title: label,
icon: /*#__PURE__*/React.createElement(DateIcon, null),
isFiltered: isFiltered,
onShowAllClick: () => onChangeFilter(null)
}, /*#__PURE__*/React.createElement(ListItem, null, /*#__PURE__*/React.createElement(DateField, {
minDate: parseDateString(min),
maxDate: parseDateString(max),
label: t(m.min),
value: filterMin || min,
onChange: handleChange('min'),
fullWidth: false,
margin: "dense",
className: cx.dateField
}), /*#__PURE__*/React.createElement(DateField, {
minDate: parseDateString(min),
maxDate: parseDateString(max),
label: t(m.max),
value: filterMax || max,
onChange: handleChange('max'),
fullWidth: false,
margin: "dense",
className: cx.dateField
})));
};
export default DateFilter;
function compileFilter(key, min, max) {
if (min === undefined && max === undefined) return null;
const filter = ['all'];
if (min) filter.push(['>=', key, min]);
if (max) filter.push(['<=', key, max]);
return filter;
}
function parseDateFilter(filter
/*:: ?: Array<any> | null*/
) {
if (!filter || filter.length < 2 || filter[0] !== 'all') return [];
const minFilter = _findInstanceProperty(filter).call(filter, d => _Array$isArray(d) && d[0] === '>=');
const maxFilter = _findInstanceProperty(filter).call(filter, d => _Array$isArray(d) && d[0] === '<=');
return [minFilter && minFilter[2], maxFilter && maxFilter[2]];
}
const useStyles = makeStyles(theme => ({
dateField: {
'&:not(:last-child)': {
marginRight: theme.spacing(1)
}
}
}));
const shortDateRegExp = /^(\d{4})-(\d{2})-(\d{2})$/;
function createFilterValue(value, minOrMax) {
const match = value.match(shortDateRegExp);
if (!match) return value;
return minOrMax === 'min' ? new Date(+match[1], +match[2] - 1, +match[3]).toISOString() : new Date(+match[1], +match[2] - 1, +match[3], 23, 59, 59, 999).toISOString();
}
//# sourceMappingURL=DateFilter.js.map