UNPKG

@mui/x-data-grid

Version:

The Community plan edition of the Data Grid components (MUI X).

255 lines (252 loc) 12 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.getGridFilter = exports.GridFilterPanel = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _forwardRef = require("@mui/x-internals/forwardRef"); var _gridFilterItem = require("../../../models/gridFilterItem"); var _useGridApiContext = require("../../../hooks/utils/useGridApiContext"); var _GridPanelContent = require("../GridPanelContent"); var _GridPanelFooter = require("../GridPanelFooter"); var _GridPanelWrapper = require("../GridPanelWrapper"); var _GridFilterForm = require("./GridFilterForm"); var _useGridRootProps = require("../../../hooks/utils/useGridRootProps"); var _useGridSelector = require("../../../hooks/utils/useGridSelector"); var _gridFilterSelector = require("../../../hooks/features/filter/gridFilterSelector"); var _gridColumnsSelector = require("../../../hooks/features/columns/gridColumnsSelector"); var _jsxRuntime = require("react/jsx-runtime"); const _excluded = ["logicOperators", "columnsSort", "filterFormProps", "getColumnForNewFilter", "children", "disableAddFilterButton", "disableRemoveAllButton"]; const getGridFilter = col => ({ field: col.field, operator: col.filterOperators[0].value, id: Math.round(Math.random() * 1e5) }); exports.getGridFilter = getGridFilter; const GridFilterPanel = exports.GridFilterPanel = (0, _forwardRef.forwardRef)(function GridFilterPanel(props, ref) { const apiRef = (0, _useGridApiContext.useGridApiContext)(); const rootProps = (0, _useGridRootProps.useGridRootProps)(); const filterModel = (0, _useGridSelector.useGridSelector)(apiRef, _gridFilterSelector.gridFilterModelSelector); const filterableColumns = (0, _useGridSelector.useGridSelector)(apiRef, _gridColumnsSelector.gridFilterableColumnDefinitionsSelector); const filterableColumnsLookup = (0, _useGridSelector.useGridSelector)(apiRef, _gridColumnsSelector.gridFilterableColumnLookupSelector); const lastFilterRef = React.useRef(null); const placeholderFilter = React.useRef(null); const { logicOperators = [_gridFilterItem.GridLogicOperator.And, _gridFilterItem.GridLogicOperator.Or], columnsSort, filterFormProps, getColumnForNewFilter, disableAddFilterButton = false, disableRemoveAllButton = false } = props, other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded); const applyFilter = apiRef.current.upsertFilterItem; const applyFilterLogicOperator = React.useCallback(operator => { apiRef.current.setFilterLogicOperator(operator); }, [apiRef]); const getDefaultFilter = React.useCallback(() => { let nextColumnWithOperator; if (getColumnForNewFilter && typeof getColumnForNewFilter === 'function') { // To allow override the column for default (first) filter const nextFieldName = getColumnForNewFilter({ currentFilters: filterModel?.items || [], columns: filterableColumns }); if (nextFieldName === null) { return null; } nextColumnWithOperator = filterableColumns.find(({ field }) => field === nextFieldName); } else { nextColumnWithOperator = filterableColumns.find(colDef => colDef.filterOperators?.length); } if (!nextColumnWithOperator) { return null; } return getGridFilter(nextColumnWithOperator); }, [filterModel?.items, filterableColumns, getColumnForNewFilter]); const getNewFilter = React.useCallback(() => { if (getColumnForNewFilter === undefined || typeof getColumnForNewFilter !== 'function') { return getDefaultFilter(); } const currentFilters = filterModel.items.length ? filterModel.items : [getDefaultFilter()].filter(Boolean); // If no items are there in filterModel, we have to pass defaultFilter const nextColumnFieldName = getColumnForNewFilter({ currentFilters: currentFilters, columns: filterableColumns }); if (nextColumnFieldName === null) { return null; } const nextColumnWithOperator = filterableColumns.find(({ field }) => field === nextColumnFieldName); if (!nextColumnWithOperator) { return null; } return getGridFilter(nextColumnWithOperator); }, [filterModel.items, filterableColumns, getColumnForNewFilter, getDefaultFilter]); const items = React.useMemo(() => { if (filterModel.items.length) { return filterModel.items; } if (!placeholderFilter.current) { placeholderFilter.current = getDefaultFilter(); } return placeholderFilter.current ? [placeholderFilter.current] : []; }, [filterModel.items, getDefaultFilter]); const hasMultipleFilters = items.length > 1; const { readOnlyFilters, validFilters } = React.useMemo(() => items.reduce((acc, item) => { if (filterableColumnsLookup[item.field]) { acc.validFilters.push(item); } else { acc.readOnlyFilters.push(item); } return acc; }, { readOnlyFilters: [], validFilters: [] }), [items, filterableColumnsLookup]); const addNewFilter = React.useCallback(() => { const newFilter = getNewFilter(); if (!newFilter) { return; } apiRef.current.upsertFilterItems([...items, newFilter]); }, [apiRef, getNewFilter, items]); const deleteFilter = React.useCallback(item => { const shouldCloseFilterPanel = validFilters.length === 1; apiRef.current.deleteFilterItem(item); if (shouldCloseFilterPanel) { apiRef.current.hideFilterPanel(); } }, [apiRef, validFilters.length]); const handleRemoveAll = React.useCallback(() => { if (validFilters.length === 1 && validFilters[0].value === undefined) { apiRef.current.deleteFilterItem(validFilters[0]); return apiRef.current.hideFilterPanel(); } return apiRef.current.setFilterModel((0, _extends2.default)({}, filterModel, { items: readOnlyFilters }), 'removeAllFilterItems'); }, [apiRef, readOnlyFilters, filterModel, validFilters]); React.useEffect(() => { if (logicOperators.length > 0 && filterModel.logicOperator && !logicOperators.includes(filterModel.logicOperator)) { applyFilterLogicOperator(logicOperators[0]); } }, [logicOperators, applyFilterLogicOperator, filterModel.logicOperator]); React.useEffect(() => { if (validFilters.length > 0) { lastFilterRef.current.focus(); } }, [validFilters.length]); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_GridPanelWrapper.GridPanelWrapper, (0, _extends2.default)({}, other, { ref: ref, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_GridPanelContent.GridPanelContent, { children: [readOnlyFilters.map((item, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridFilterForm.GridFilterForm, (0, _extends2.default)({ item: item, applyFilterChanges: applyFilter, deleteFilter: deleteFilter, hasMultipleFilters: hasMultipleFilters, showMultiFilterOperators: index > 0, disableMultiFilterOperator: index !== 1, applyMultiFilterOperatorChanges: applyFilterLogicOperator, focusElementRef: null, readOnly: true, logicOperators: logicOperators, columnsSort: columnsSort }, filterFormProps), item.id == null ? index : item.id)), validFilters.map((item, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_GridFilterForm.GridFilterForm, (0, _extends2.default)({ item: item, applyFilterChanges: applyFilter, deleteFilter: deleteFilter, hasMultipleFilters: hasMultipleFilters, showMultiFilterOperators: readOnlyFilters.length + index > 0, disableMultiFilterOperator: readOnlyFilters.length + index !== 1, applyMultiFilterOperatorChanges: applyFilterLogicOperator, focusElementRef: index === validFilters.length - 1 ? lastFilterRef : null, logicOperators: logicOperators, columnsSort: columnsSort }, filterFormProps), item.id == null ? index + readOnlyFilters.length : item.id))] }), !rootProps.disableMultipleColumnsFiltering && !(disableAddFilterButton && disableRemoveAllButton) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_GridPanelFooter.GridPanelFooter, { children: [!disableAddFilterButton ? /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseButton, (0, _extends2.default)({ onClick: addNewFilter, startIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.filterPanelAddIcon, {}) }, rootProps.slotProps?.baseButton, { children: apiRef.current.getLocaleText('filterPanelAddFilter') })) : /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {}), !disableRemoveAllButton && validFilters.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.baseButton, (0, _extends2.default)({ onClick: handleRemoveAll, startIcon: /*#__PURE__*/(0, _jsxRuntime.jsx)(rootProps.slots.filterPanelRemoveAllIcon, {}) }, rootProps.slotProps?.baseButton, { children: apiRef.current.getLocaleText('filterPanelRemoveAll') })) : null] }) : null] })); }); process.env.NODE_ENV !== "production" ? GridFilterPanel.propTypes = { // ----------------------------- Warning -------------------------------- // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "pnpm proptypes" | // ---------------------------------------------------------------------- /** * @ignore - do not document. */ children: _propTypes.default.node, /** * Changes how the options in the columns selector should be ordered. * If not specified, the order is derived from the `columns` prop. */ columnsSort: _propTypes.default.oneOf(['asc', 'desc']), /** * If `true`, the `Add filter` button will not be displayed. * @default false */ disableAddFilterButton: _propTypes.default.bool, /** * If `true`, the `Remove all` button will be disabled * @default false */ disableRemoveAllButton: _propTypes.default.bool, /** * Props passed to each filter form. */ filterFormProps: _propTypes.default.shape({ columnInputProps: _propTypes.default.any, columnsSort: _propTypes.default.oneOf(['asc', 'desc']), deleteIconProps: _propTypes.default.any, filterColumns: _propTypes.default.func, logicOperatorInputProps: _propTypes.default.any, operatorInputProps: _propTypes.default.any, valueInputProps: _propTypes.default.any }), /** * Function that returns the next filter item to be picked as default filter. * @param {GetColumnForNewFilterArgs} args Currently configured filters and columns. * @returns {GridColDef['field']} The field to be used for the next filter or `null` to prevent adding a filter. */ getColumnForNewFilter: _propTypes.default.func, /** * Sets the available logic operators. * @default [GridLogicOperator.And, GridLogicOperator.Or] */ logicOperators: _propTypes.default.arrayOf(_propTypes.default.oneOf(['and', 'or']).isRequired), /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object, _propTypes.default.bool])), _propTypes.default.func, _propTypes.default.object]) } : void 0; /** * Demos: * - [Filtering - overview](https://mui.com/x/react-data-grid/filtering/) * * API: * - [GridFilterPanel API](https://mui.com/x/api/data-grid/grid-filter-panel/) */