react-mapfilter
Version:
These components are designed for viewing data in Mapeo. They share a common interface:
228 lines (185 loc) • 8.29 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
var _Object$defineProperty = require("@babel/runtime-corejs3/core-js-stable/object/define-property");
_Object$defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _indexOf = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/index-of"));
var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice"));
var _stringify = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/json/stringify"));
var _find = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/find"));
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
var _concat = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/concat"));
var _sort = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/sort"));
var _set = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/set"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/toConsumableArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof"));
var _reduce = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/reduce"));
var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter"));
var React = _interopRequireWildcard(require("react"));
var _StyledCheckbox = _interopRequireDefault(require("./StyledCheckbox"));
var _List = _interopRequireDefault(require("@material-ui/icons/List"));
var _styles = require("@material-ui/core/styles");
var _ListItem = _interopRequireDefault(require("@material-ui/core/ListItem"));
var _ListItemIcon = _interopRequireDefault(require("@material-ui/core/ListItemIcon"));
var _ListItemSecondaryAction = _interopRequireDefault(require("@material-ui/core/ListItemSecondaryAction"));
var _ListItemText = _interopRequireDefault(require("@material-ui/core/ListItemText"));
var _FilterSection = _interopRequireDefault(require("./FilterSection"));
var _OnlyButton = _interopRequireDefault(require("./OnlyButton"));
var _data_analysis = require("../lib/data_analysis");
var _FormattedValue = _interopRequireDefault(require("../internal/FormattedValue"));
// @flow
// import {FIELD_TYPE_BOOLEAN, FIELD_TYPE_NUMBER} from '../../constants'
var FilterItem = function FilterItem(_ref) {
var onClick = _ref.onClick,
checked = _ref.checked,
label = _ref.label,
id = _ref.id,
onOnlyClick = _ref.onOnlyClick;
var cx = useStyles();
return /*#__PURE__*/React.createElement(_ListItem.default, {
role: undefined,
dense: true,
button: true,
onClick: onClick,
className: cx.filterItem
}, /*#__PURE__*/React.createElement(_ListItemIcon.default, {
className: cx.checkboxIcon
}, /*#__PURE__*/React.createElement(_StyledCheckbox.default, {
edge: "start",
checked: checked,
tabIndex: -1,
disableRipple: true,
inputProps: {
'aria-labelledby': id
},
className: cx.checkbox
})), /*#__PURE__*/React.createElement(_ListItemText.default, {
id: id,
primary: label
}), /*#__PURE__*/React.createElement(_ListItemSecondaryAction.default, null, /*#__PURE__*/React.createElement(_OnlyButton.default, {
className: cx.onlyButton,
onClick: onOnlyClick
})));
};
/*:: type Props = {
label: React.Node,
fieldKey: Key,
filter?: Filter | null,
options: SelectOptions,
onChangeFilter: (filter: Array<any> | null) => void
}*/
var DiscreteFilter = function DiscreteFilter(_ref2) {
var _context, _context2;
var label = _ref2.label,
fieldKey = _ref2.fieldKey,
filter = (0, _filter.default)(_ref2),
options = _ref2.options,
onChangeFilter = _ref2.onChangeFilter;
var values
/*: Array<number | string | boolean>*/
= (0, _reduce.default)(options).call(options, function (acc, cur) {
// Filter null values
if (cur == null) return acc;
if ((0, _typeof2.default)(cur) === 'object' && cur.value != null) acc.push(cur.value);else if ((0, _typeof2.default)(cur) !== 'object') acc.push(cur);
return acc;
}, []);
var shownValues = valuesFromFilter(filter, values);
var allValues = (0, _toConsumableArray2.default)(new _set.default((0, _sort.default)(_context = (0, _concat.default)(_context2 = []).call(_context2, (0, _toConsumableArray2.default)(shownValues), (0, _toConsumableArray2.default)(values))).call(_context)));
var handleClick = function handleClick(value) {
return function (e) {
var _context3, _context4;
if (shownValues.has(value)) shownValues.delete(value);else shownValues.add(value);
var newFilter = // If all items are selected we're implicitly including undefined and null
// values, so we clear the filter altogether if everything is selected
shownValues.size === allValues.length ? null : shownValues.size > 0 ? (0, _concat.default)(_context3 = ['in', fieldKey]).call(_context3, (0, _toConsumableArray2.default)(shownValues)) : (0, _concat.default)(_context4 = ['!in', fieldKey]).call(_context4, (0, _toConsumableArray2.default)(allValues));
onChangeFilter(newFilter);
};
};
var handleOnlyClick = function handleOnlyClick(value) {
return function () {
onChangeFilter(['in', fieldKey, value]);
};
}; // Don't render the filter if there is nothing to choose from
if (!allValues || allValues.length === 0) return null;
return /*#__PURE__*/React.createElement(_FilterSection.default, {
title: label,
icon: /*#__PURE__*/React.createElement(_List.default, null),
isFiltered: !!filter,
onShowAllClick: function onShowAllClick() {
return onChangeFilter(null);
}
}, (0, _map.default)(allValues).call(allValues, function (v, i) {
// TODO use FormattedValue here
var option = (0, _find.default)(options).call(options, function (o) {
return (0, _typeof2.default)(o) === 'object' && o !== null && o.value === v;
});
var label = option ? // $FlowFixMe - pretty sure the find above means this must have a label prop
option.label : v == null ? '[No Value]' :
/*#__PURE__*/
// This is kind of a hack just to re-use code that detects and formats dates if they are options
React.createElement(_FormattedValue.default, {
value: v,
field: (0, _data_analysis.getField)([], v)
});
var key = (0, _stringify.default)(v);
return /*#__PURE__*/React.createElement(FilterItem, {
key: key,
id: key,
label: label,
checked: shownValues.has(v),
onClick: handleClick(v),
onOnlyClick: handleOnlyClick(v)
});
}));
};
function valuesFromFilter(filter)
/*: Set<SelectableFieldValue>*/
{
var values = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
if (!filter || filter.length < 3) return new _set.default(values); // $FlowFixMe - need to better define type for filter
if (filter[0] === 'in') return new _set.default((0, _slice.default)(filter).call(filter, 2));
if (filter[0] === '!in') {
var notShown = (0, _slice.default)(filter).call(filter, 2);
var shown = (0, _filter.default)(values).call(values, function (v) {
return (0, _indexOf.default)(notShown).call(notShown, v) < 0;
});
return new _set.default(shown);
}
return new _set.default(values);
}
var _default = DiscreteFilter;
exports.default = _default;
var useStyles = (0, _styles.makeStyles)(function (theme) {
return {
filterItem: {
paddingTop: 0,
paddingBottom: 0,
'& $onlyButton': {
display: 'none'
},
'&:hover $onlyButton': {
display: 'block'
}
},
onlyButton: {
fontSize: 12,
lineHeight: '16px',
minWidth: 'auto'
},
checkboxIcon: {
minWidth: 36,
paddingLeft: 4
},
checkbox: {
padding: 0,
paddingLeft: 12,
'&:hover': {
backgroundColor: 'inherit !important'
}
}
};
});
//# sourceMappingURL=DiscreteFilter.js.map