UNPKG

@krowdy-ui/views

Version:

React components that implement Google's Material Design.

598 lines (566 loc) 21.9 kB
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; import _extends from "@babel/runtime/helpers/esm/extends"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; var _excluded = ["_id"]; import React, { useCallback, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import AddIcon from '@material-ui/icons/Add'; import { IconButton, Divider } from '@material-ui/core'; import ArrowBackIcon from '@material-ui/icons/ArrowBackIos'; import { Button, Card, CardContent, CardHeader, TabPanel, Typography, withStyles } from '@krowdy-ui/core'; import FiltersTree from './FiltersTree'; import FilterConfig from './FilterConfig'; import FiltersList from './FiltersList'; import DividerWithText from './DividerWithText'; import { mongoObjectId } from '../utils/mongoObjectId'; import { AddToPhotos as AddToPhotosIcon, Delete as DeleteIcon, Face as FaceIcon } from '@material-ui/icons'; import { generateRandomId } from '../utils'; import KeywordFilter from './KeywordFilter'; export var styles = function styles(theme) { return { backIcon: { marginRight: theme.spacing(1), paddingLeft: theme.spacing(.75), paddingRight: 0 }, block: { width: 18 }, buttonAddContainer: { alignItems: 'center', display: 'flex', justifyContent: 'space-between', marginTop: theme.spacing(1) }, buttonAddGroupFilter: { borderStyle: 'dashed', margin: theme.spacing(1.5, 0) }, cardContent: { display: 'flex', flex: 2, justifyContent: 'center', overflowY: 'auto' }, cardTitle: { fontSize: 14 }, center: { alignItems: 'center', display: 'flex', flexDirection: 'column' }, flex: { alignItems: 'center', display: 'flex' }, groupFilterContainer: { '&:hover': { backgroundColor: theme.palette.primary[50], border: "1px solid ".concat(theme.palette.primary[500]) }, backgroundColor: theme.palette.secondary[10], border: "1px solid ".concat(theme.palette.secondary[10]), borderRadius: 2 * theme.shape.borderRadius, overflowX: 'auto', padding: theme.spacing(0.5) }, groupFilterContainerBlock: { '&:hover': { backgroundColor: theme.palette.secondary[100], border: "1px solid ".concat(theme.palette.secondary[200]) }, backgroundColor: theme.palette.secondary[100], border: "1px solid ".concat(theme.palette.secondary[100]), borderRadius: theme.shape.borderRadius, overflowX: 'auto', padding: theme.spacing(0.5) }, littleMarginLeft: { marginLeft: theme.spacing(.5) }, marginTop: { marginTop: theme.spacing(1.5) }, noPadding: { padding: 0 }, root: { display: 'flex', flexFlow: 'column', height: '100%' }, spaceBetween: { justifyContent: 'space-between', width: '100%' }, titleBack: { fontSize: 14 }, titleContainer: { alignItems: 'center', display: 'flex', height: 20 }, treeContainer: { '& *, & *::after, & *::before': { boxSizing: 'content-box' }, overflowY: 'scroll' }, viewContainer: { height: '100%', width: '100%' } }; }; var Views = { FILTERS_SEARCH: { backIndex: 'HOME', index: 1, withPadding: false }, FILTER_CONFIG: { backIndex: 'FILTERS_SEARCH', index: 2, withPadding: true }, HOME: { index: 0, withPadding: true } }; var CandidateGroupFilterType = { Excluded: 'excluded', Included: 'included' }; var _ref4 = /*#__PURE__*/React.createElement(ArrowBackIcon, { fontSize: "inherit" }); var _ref5 = /*#__PURE__*/React.createElement(AddIcon, null); var _ref6 = /*#__PURE__*/React.createElement(FaceIcon, { color: "disabled" }); var _ref7 = /*#__PURE__*/React.createElement(DividerWithText, { title: 'or' }); var _ref8 = /*#__PURE__*/React.createElement(AddIcon, null); var _ref9 = /*#__PURE__*/React.createElement(DeleteIcon, { fontSize: "small" }); var _ref10 = /*#__PURE__*/React.createElement(DividerWithText, { title: 'or' }); var SuperFilters = function SuperFilters(props) { var classes = props.classes, listRef = props.listRef, _props$title = props.title, title = _props$title === void 0 ? 'Todos las compras' : _props$title, _props$headerHomeComp = props.headerHomeComponent, HeaderHomeComponent = _props$headerHomeComp === void 0 ? null : _props$headerHomeComp, _props$filters = props.filters, filters = _props$filters === void 0 ? [] : _props$filters, _props$onChangeFilter = props.onChangeFilters, onChangeFilters = _props$onChangeFilter === void 0 ? function () {} : _props$onChangeFilter, onSelectCategoryFilter = props.onSelectCategoryFilter, _props$categoryItems = props.categoryItems, categoryItems = _props$categoryItems === void 0 ? [] : _props$categoryItems, _props$hasNextPage = props.hasNextPage, hasNextPage = _props$hasNextPage === void 0 ? false : _props$hasNextPage, _props$filterTypes = props.filterTypes, filterTypes = _props$filterTypes === void 0 ? [] : _props$filterTypes, _props$loadMoreCatego = props.loadMoreCategoryItems, loadMoreCategoryItems = _props$loadMoreCatego === void 0 ? function () {} : _props$loadMoreCatego, _props$isLoadingMoreC = props.isLoadingMoreCategoryItems, isLoadingMoreCategoryItems = _props$isLoadingMoreC === void 0 ? false : _props$isLoadingMoreC, listWidth = props.listWidth, _props$filterGroups = props.filterGroups, filterGroups = _props$filterGroups === void 0 ? [] : _props$filterGroups, _props$dots = props.dots, dots = _props$dots === void 0 ? false : _props$dots, _props$uniqueFilter = props.uniqueFilter, uniqueFilter = _props$uniqueFilter === void 0 ? false : _props$uniqueFilter, totalItems = props.totalItems, _props$onChangeFilter2 = props.onChangeFilterCandidate, onChangeFilterCandidate = _props$onChangeFilter2 === void 0 ? function () {} : _props$onChangeFilter2, _props$excludedCandid = props.excludedCandidates, excludedCandidates = _props$excludedCandid === void 0 ? [] : _props$excludedCandid, _props$childProps = props.childProps, childProps = _props$childProps === void 0 ? {} : _props$childProps, _props$includedCandid = props.includedCandidates, includedCandidates = _props$includedCandid === void 0 ? [] : _props$includedCandid, viewDefault = props.viewDefault, shortcuts = props.shortcuts; var PaperProps = childProps.PaperProps, AddFiltersButtonProps = childProps.AddFiltersButtonProps; var _useState = useState(null), _useState2 = _slicedToArray(_useState, 2), groupFilterCurrent = _useState2[0], setGroupFilterCurrent = _useState2[1]; var _useState3 = useState(Views[viewDefault] || Views.HOME), _useState4 = _slicedToArray(_useState3, 2), view = _useState4[0], goToView = _useState4[1]; var _useState5 = useState(), _useState6 = _slicedToArray(_useState5, 2), filterSelected = _useState6[0], setFilterSelected = _useState6[1]; var _useState7 = useState(), _useState8 = _slicedToArray(_useState7, 2), filterToEdit = _useState8[0], setFilterToEdit = _useState8[1]; var _useState9 = useState(false), _useState10 = _slicedToArray(_useState9, 2), openKeywordFilter = _useState10[0], setOpenKeywordFilter = _useState10[1]; var _useMemo = useMemo(function () { return { groupFilterCurrentChildren: groupFilterCurrent ? groupFilterCurrent.children : null, groupFilterCurrentKey: groupFilterCurrent ? groupFilterCurrent.key : null }; }, [groupFilterCurrent]), groupFilterCurrentKey = _useMemo.groupFilterCurrentKey, groupFilterCurrentChildren = _useMemo.groupFilterCurrentChildren; var addFilter = useCallback(function (filter) { onChangeFilters(filters.map(function (groupFilter) { if (groupFilter.key !== groupFilterCurrentKey) return groupFilter; return _extends({}, groupFilter, { children: groupFilter.children.concat(filter) }); })); }, [filters, groupFilterCurrentKey, onChangeFilters]); var deepUpdate = useCallback(function (arr, _ref) { var _id = _ref._id, updatedItem = _objectWithoutProperties(_ref, _excluded); return arr.map(function (item) { if (item._id === _id) return _extends({}, item, updatedItem); if (Array.isArray(item.children) && item.children.length) return _extends({}, item, { children: deepUpdate(item.children, _extends({ _id: _id }, updatedItem)) }); return item; }); }, []); var updateFilter = useCallback(function (filter) { var updatedFilters = deepUpdate(groupFilterCurrentChildren, filter); onChangeFilters(filters.map(function (groupFilter) { if (groupFilter.key !== groupFilterCurrentKey) return groupFilter; return _extends({}, groupFilter, { children: updatedFilters }); })); }, [deepUpdate, filters, groupFilterCurrentChildren, groupFilterCurrentKey, onChangeFilters]); // Aqui es cuando se agrega un filtro var _handleClickApplyFilters = useCallback(function (filter) { if (Object.values(CandidateGroupFilterType).includes(groupFilterCurrentKey)) onChangeFilterCandidate(groupFilterCurrentKey, filter.value);else if (filters.some(function (_ref2) { var key = _ref2.key; return key === groupFilterCurrentKey; })) { if (filterToEdit) { // Exists, so update it updateFilter(filter); setFilterToEdit(null); } else { addFilter(filter); } } else onChangeFilters(filters.concat({ children: [filter], key: mongoObjectId(), operator: 'none', type: 'default' })); goToView(Views.HOME); setGroupFilterCurrent(null); setOpenKeywordFilter(false); }, [addFilter, filterToEdit, filters, groupFilterCurrentKey, onChangeFilterCandidate, onChangeFilters, updateFilter]); var _handleClickFilterListItem = useCallback(function (item) { if (item.type === 'shortcut') { setFilterSelected(item.treeData); var _item$treeData = _slicedToArray(item.treeData, 1), tree = _item$treeData[0]; _handleClickApplyFilters(tree); } else { setFilterSelected(item); if (item.type === 'keyword') setOpenKeywordFilter(true);else goToView(Views.FILTER_CONFIG); } }, [_handleClickApplyFilters]); var _handleClickAddFilter = useCallback(function (groupFilter) { return function () { setGroupFilterCurrent(groupFilter); goToView(Views.FILTERS_SEARCH); }; }, []); var _handleClickAddGroupFilter = useCallback(function () { setGroupFilterCurrent({ children: [], key: mongoObjectId(), operator: 'none', type: 'default' }); goToView(Views.FILTERS_SEARCH); }, []); var _handleClickDeleteGroupFilter = useCallback(function (groupFilterKey) { return function () { onChangeFilters(filters.filter(function (groupFilter) { return groupFilter.key !== groupFilterKey; })); }; }, [filters, onChangeFilters]); var _handleClickBack = useCallback(function () { if ([CandidateGroupFilterType.Included, CandidateGroupFilterType.Excluded].includes(groupFilterCurrentKey)) { goToView(Views.HOME); setFilterToEdit(null); setGroupFilterCurrent(null); return; } goToView(Views[view.backIndex]); setFilterToEdit(null); if (view.backIndex === 'HOME') setGroupFilterCurrent(null); }, [groupFilterCurrentKey, view.backIndex]); var _handleChangeFilterTree = useCallback(function (groupFilterKey) { return function (treeFilters) { onChangeFilters(filters.map(function (groupFilter) { if (groupFilterKey !== groupFilter.key) return groupFilter; return _extends({}, groupFilter, { children: treeFilters }); }).filter(function (_ref3) { var children = _ref3.children; return children.length; })); }; }, [filters, onChangeFilters]); var _handleClickEditFilter = useCallback(function (groupFilter) { return function (appliedFilter) { setGroupFilterCurrent(groupFilter); setFilterToEdit(appliedFilter); if (appliedFilter.type === 'keyword') setOpenKeywordFilter(true);else goToView(Views.FILTER_CONFIG); }; }, []); var _handleChangeFilterCandidates = useCallback(function (candidateGroupFilterType) { return function () { onChangeFilterCandidate(candidateGroupFilterType, []); }; }, [onChangeFilterCandidate]); var _handleClickEditFilterCandidates = useCallback(function (candidateGroupFilterType) { return function (treeFilters) { setGroupFilterCurrent({ key: candidateGroupFilterType }); setFilterToEdit(treeFilters); goToView(Views.FILTER_CONFIG); }; }, []); var _handleCloseKeywordFilter = useCallback(function () { setOpenKeywordFilter(false); }, []); return /*#__PURE__*/React.createElement(Card, { className: classes.root, variant: "outlined" }, /*#__PURE__*/React.createElement(CardHeader, { shadow: true, title: /*#__PURE__*/React.createElement("div", { className: classes.titleContainer }, view.index !== 0 && /*#__PURE__*/React.createElement(IconButton, { "aria-label": "delete", className: classes.backIcon, onClick: _handleClickBack, size: "small" }, _ref4), /*#__PURE__*/React.createElement("p", { className: classes.titleBack }, view.index === 0 ? title : 'Atrás')) }), /*#__PURE__*/React.createElement(CardContent, { className: clsx(classes.cardContent, !view.withPadding && classes.noPadding) }, /*#__PURE__*/React.createElement(TabPanel, { className: classes.viewContainer, index: Views.HOME.index, value: view.index }, filters.length === 0 ? HeaderHomeComponent : null, !filters.length && !includedCandidates.length && !excludedCandidates.length ? /*#__PURE__*/React.createElement(Button, { color: "primary", fullWidth: true, onClick: _handleClickAddGroupFilter, startIcon: _ref5 }, "A\xF1adir Filtro") : /*#__PURE__*/React.createElement("div", { className: clsx(classes.flex, classes.spaceBetween) }, /*#__PURE__*/React.createElement(IconButton, { color: "primary", size: "small" }, /*#__PURE__*/React.createElement(AddToPhotosIcon, { fontSize: "small", onClick: _handleClickAddGroupFilter })), !isNaN(totalItems) ? /*#__PURE__*/React.createElement("div", { className: classes.flex }, _ref6, /*#__PURE__*/React.createElement(Typography, { className: classes.littleMarginLeft, variant: "body1" }, totalItems, " resultado", totalItems > 1 ? 's' : '')) : null), /*#__PURE__*/React.createElement("div", { className: clsx(classes.marginTop, classes.treeContainer) }, excludedCandidates.length ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { className: classes.groupFilterContainerBlock }, /*#__PURE__*/React.createElement(FiltersTree, { dots: dots, onChange: _handleChangeFilterCandidates(CandidateGroupFilterType.Excluded), onClickEdit: _handleClickEditFilterCandidates(CandidateGroupFilterType.Excluded), treeData: [{ _id: generateRandomId(), key: '_id', label: 'Candidato', operator: '$nin', operatorLabel: 'no es', optionIndex: 1, reference: null, type: 'list', value: excludedCandidates }] })), includedCandidates.length || filters.length ? /*#__PURE__*/React.createElement(Divider, { className: classes.marginTop }) : null) : null, includedCandidates.length ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { className: clsx(classes.marginTop, classes.groupFilterContainer) }, /*#__PURE__*/React.createElement(FiltersTree, { dots: dots, onChange: _handleChangeFilterCandidates(CandidateGroupFilterType.Included), onClickEdit: _handleClickEditFilterCandidates(CandidateGroupFilterType.Included), treeData: [{ _id: generateRandomId(), key: '_id', label: 'Candidato', operator: '$in', operatorLabel: 'es', optionIndex: 0, reference: null, type: 'list', value: includedCandidates }] })), filters.length ? _ref7 : null) : null, filters.map(function (groupFilter, index) { return /*#__PURE__*/React.createElement("div", { key: "GroupFilterDefault-".concat(index) }, /*#__PURE__*/React.createElement("div", { className: classes.groupFilterContainer }, /*#__PURE__*/React.createElement(FiltersTree, { dots: dots, onChange: _handleChangeFilterTree(groupFilter.key), onClickEdit: _handleClickEditFilter(groupFilter), treeData: groupFilter.children }), /*#__PURE__*/React.createElement("div", { className: classes.buttonAddContainer }, /*#__PURE__*/React.createElement("div", { className: classes.block }), /*#__PURE__*/React.createElement(Button, { color: "primary", onClick: _handleClickAddFilter(groupFilter), startIcon: _ref8 }, "Filtro"), groupFilter.children.length ? /*#__PURE__*/React.createElement("div", { className: classes.block }) : /*#__PURE__*/React.createElement(IconButton, { color: "primary", onClick: _handleClickDeleteGroupFilter(groupFilter.key), size: "small" }, _ref9))), index + 1 < filters.length && _ref10); }))), /*#__PURE__*/React.createElement(TabPanel, { className: classes.viewContainer, index: Views.FILTERS_SEARCH.index, value: view.index }, /*#__PURE__*/React.createElement(FiltersList, { filterGroups: shortcuts && shortcuts.length ? filterGroups.concat(shortcuts) : filterGroups, filters: groupFilterCurrent ? groupFilterCurrent.children : [], listRef: listRef, onClickItem: _handleClickFilterListItem, uniqueFilter: uniqueFilter })), /*#__PURE__*/React.createElement(TabPanel, { className: classes.viewContainer, index: Views.FILTER_CONFIG.index, value: view.index }, /*#__PURE__*/React.createElement(FilterConfig, { AddFiltersButtonProps: AddFiltersButtonProps, categoryItems: categoryItems, edit: filterToEdit ? true : false, filter: filterToEdit || filterSelected, filterTypes: filterTypes, hasNextPage: hasNextPage, listWidth: listWidth, loadMoreCategoryItems: loadMoreCategoryItems, onClickApply: _handleClickApplyFilters, onSelectCategoryFilter: onSelectCategoryFilter, PaperProps: PaperProps })), /*#__PURE__*/React.createElement(KeywordFilter, { edit: !!filterToEdit, filter: filterToEdit || filterSelected, isLoading: isLoadingMoreCategoryItems, isOpen: openKeywordFilter, items: categoryItems, loadMore: loadMoreCategoryItems, onClickApply: _handleClickApplyFilters, onClose: _handleCloseKeywordFilter, onResetCategoryItems: onSelectCategoryFilter, PaperProps: PaperProps }))); }; process.env.NODE_ENV !== "production" ? SuperFilters.propTypes = { categoryItems: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.string.isRequired, label: PropTypes.string.isRequired })).isRequired, childProps: PropTypes.object, classes: PropTypes.object, excludedCandidates: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, label: PropTypes.string })), filterGroups: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.string.isRequired, children: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.string.isRequired, key: PropTypes.string.isRequired, label: PropTypes.string.isRequired, type: PropTypes.string.isRequired })), label: PropTypes.string.isRequired })), filterTypes: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.string.isRequired, initialValue: PropTypes.any.isRequired, options: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.string.isRequired, label: PropTypes.string.isRequired, numberOfInputs: PropTypes.number.isRequired, operator: PropTypes.string.isRequired })).isRequired, type: PropTypes.string.isRequired })).isRequired, filters: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.string, key: PropTypes.string.isRequired, label: PropTypes.string, operator: PropTypes.string.isRequired, operatorLabel: PropTypes.string, optionIndex: PropTypes.number, type: PropTypes.string.isRequired, value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]) })), hasNextPage: PropTypes.bool, headerHomeComponent: PropTypes.node, includedCandidates: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, label: PropTypes.string })), isLoadingMoreCategoryItems: PropTypes.bool, listWidth: PropTypes.number, loadMoreCategoryItems: PropTypes.func, onChangeFilterCandidate: PropTypes.func, onChangeFilters: PropTypes.func.isRequired, onFetchFilterGroups: PropTypes.func, onSelectCategoryFilter: PropTypes.func, shortcuts: PropTypes.arrayOf(PropTypes.shape({ _id: PropTypes.string, children: PropTypes.array, label: PropTypes.string, type: PropTypes.string.isRequired })), title: PropTypes.string.isRequired, uniqueFilter: PropTypes.bool, viewDefault: PropTypes.oneOf(['HOME', 'FILTERS_SEARCH', 'FILTER_CONFIG']) } : void 0; export default withStyles(styles, { name: 'SuperFilters' })(SuperFilters);