UNPKG

@mui/x-data-grid

Version:

The community edition of the data grid component (MUI X).

318 lines (265 loc) 13.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.useGridSorting = exports.sortingStateInitializer = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _gridFeatureMode = require("../../../models/gridFeatureMode"); var _keyboardUtils = require("../../../utils/keyboardUtils"); var _useGridApiEventHandler = require("../../utils/useGridApiEventHandler"); var _useGridApiMethod = require("../../utils/useGridApiMethod"); var _useGridLogger = require("../../utils/useGridLogger"); var _gridColumnsSelector = require("../columns/gridColumnsSelector"); var _gridSortingSelector = require("./gridSortingSelector"); var _rows = require("../rows"); var _useFirstRender = require("../../utils/useFirstRender"); var _strategyProcessing = require("../../core/strategyProcessing"); var _gridSortingUtils = require("./gridSortingUtils"); var _pipeProcessing = require("../../core/pipeProcessing"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } const sortingStateInitializer = (state, props) => { var _ref, _props$sortModel, _props$initialState, _props$initialState$s; const sortModel = (_ref = (_props$sortModel = props.sortModel) != null ? _props$sortModel : (_props$initialState = props.initialState) == null ? void 0 : (_props$initialState$s = _props$initialState.sorting) == null ? void 0 : _props$initialState$s.sortModel) != null ? _ref : []; return (0, _extends2.default)({}, state, { sorting: { sortModel: (0, _gridSortingUtils.sanitizeSortModel)(sortModel, props.disableMultipleColumnsSorting), sortedRows: [] } }); }; /** * @requires useGridRows (event) * @requires useGridColumns (event) */ exports.sortingStateInitializer = sortingStateInitializer; const useGridSorting = (apiRef, props) => { var _props$initialState3, _props$initialState3$; const logger = (0, _useGridLogger.useGridLogger)(apiRef, 'useGridSorting'); apiRef.current.unstable_registerControlState({ stateId: 'sortModel', propModel: props.sortModel, propOnChange: props.onSortModelChange, stateSelector: _gridSortingSelector.gridSortModelSelector, changeEvent: 'sortModelChange' }); const upsertSortModel = React.useCallback((field, sortItem) => { const sortModel = (0, _gridSortingSelector.gridSortModelSelector)(apiRef); const existingIdx = sortModel.findIndex(c => c.field === field); let newSortModel = [...sortModel]; if (existingIdx > -1) { if (!sortItem) { newSortModel.splice(existingIdx, 1); } else { newSortModel.splice(existingIdx, 1, sortItem); } } else { newSortModel = [...sortModel, sortItem]; } return newSortModel; }, [apiRef]); const createSortItem = React.useCallback((col, directionOverride) => { var _col$sortingOrder2; const sortModel = (0, _gridSortingSelector.gridSortModelSelector)(apiRef); const existing = sortModel.find(c => c.field === col.field); if (existing) { var _col$sortingOrder; const nextSort = directionOverride === undefined ? (0, _gridSortingUtils.getNextGridSortDirection)((_col$sortingOrder = col.sortingOrder) != null ? _col$sortingOrder : props.sortingOrder, existing.sort) : directionOverride; return nextSort == null ? undefined : (0, _extends2.default)({}, existing, { sort: nextSort }); } return { field: col.field, sort: directionOverride === undefined ? (0, _gridSortingUtils.getNextGridSortDirection)((_col$sortingOrder2 = col.sortingOrder) != null ? _col$sortingOrder2 : props.sortingOrder) : directionOverride }; }, [apiRef, props.sortingOrder]); /** * API METHODS */ const applySorting = React.useCallback(() => { apiRef.current.setState(state => { if (props.sortingMode === _gridFeatureMode.GridFeatureModeConstant.server) { logger.debug('Skipping sorting rows as sortingMode = server'); return (0, _extends2.default)({}, state, { sorting: (0, _extends2.default)({}, state.sorting, { sortedRows: (0, _rows.gridRowIdsSelector)(state, apiRef.current.instanceId) }) }); } const sortModel = (0, _gridSortingSelector.gridSortModelSelector)(state, apiRef.current.instanceId); const sortRowList = (0, _gridSortingUtils.buildAggregatedSortingApplier)(sortModel, apiRef); const sortedRows = apiRef.current.unstable_applyStrategyProcessor('sorting', { sortRowList }); return (0, _extends2.default)({}, state, { sorting: (0, _extends2.default)({}, state.sorting, { sortedRows }) }); }); apiRef.current.publishEvent('sortedRowsSet'); apiRef.current.forceUpdate(); }, [apiRef, logger, props.sortingMode]); const setSortModel = React.useCallback(model => { const currentModel = (0, _gridSortingSelector.gridSortModelSelector)(apiRef); if (currentModel !== model) { logger.debug(`Setting sort model`); apiRef.current.setState((0, _gridSortingUtils.mergeStateWithSortModel)(model, props.disableMultipleColumnsSorting)); apiRef.current.forceUpdate(); apiRef.current.applySorting(); } }, [apiRef, logger, props.disableMultipleColumnsSorting]); const sortColumn = React.useCallback((column, direction, allowMultipleSorting) => { if (!column.sortable) { return; } const sortItem = createSortItem(column, direction); let sortModel; if (!allowMultipleSorting || props.disableMultipleColumnsSorting) { sortModel = !sortItem ? [] : [sortItem]; } else { sortModel = upsertSortModel(column.field, sortItem); } apiRef.current.setSortModel(sortModel); }, [apiRef, upsertSortModel, createSortItem, props.disableMultipleColumnsSorting]); const getSortModel = React.useCallback(() => (0, _gridSortingSelector.gridSortModelSelector)(apiRef), [apiRef]); const getSortedRows = React.useCallback(() => { const sortedRows = (0, _gridSortingSelector.gridSortedRowEntriesSelector)(apiRef); return sortedRows.map(row => row.model); }, [apiRef]); const getSortedRowIds = React.useCallback(() => (0, _gridSortingSelector.gridSortedRowIdsSelector)(apiRef), [apiRef]); const getRowIndex = React.useCallback(id => apiRef.current.getSortedRowIds().indexOf(id), [apiRef]); const getRowIdFromRowIndex = React.useCallback(index => apiRef.current.getSortedRowIds()[index], [apiRef]); const sortApi = { getSortModel, getSortedRows, getSortedRowIds, getRowIndex, getRowIdFromRowIndex, setSortModel, sortColumn, applySorting }; (0, _useGridApiMethod.useGridApiMethod)(apiRef, sortApi, 'GridSortApi'); /** * PRE-PROCESSING */ const stateExportPreProcessing = React.useCallback((prevState, context) => { var _props$initialState2, _props$initialState2$; const sortModelToExport = (0, _gridSortingSelector.gridSortModelSelector)(apiRef); const shouldExportSortModel = // Always export if the `exportOnlyDirtyModels` property is activated !context.exportOnlyDirtyModels || // Always export if the model is controlled props.sortModel != null || // Always export if the model has been initialized ((_props$initialState2 = props.initialState) == null ? void 0 : (_props$initialState2$ = _props$initialState2.sorting) == null ? void 0 : _props$initialState2$.sortModel) != null || // Export if the model is not empty sortModelToExport.length > 0; if (!shouldExportSortModel) { return prevState; } return (0, _extends2.default)({}, prevState, { sorting: { sortModel: sortModelToExport } }); }, [apiRef, props.sortModel, (_props$initialState3 = props.initialState) == null ? void 0 : (_props$initialState3$ = _props$initialState3.sorting) == null ? void 0 : _props$initialState3$.sortModel]); const stateRestorePreProcessing = React.useCallback((params, context) => { var _context$stateToResto; const sortModel = (_context$stateToResto = context.stateToRestore.sorting) == null ? void 0 : _context$stateToResto.sortModel; if (sortModel == null) { return params; } apiRef.current.setState((0, _gridSortingUtils.mergeStateWithSortModel)(sortModel, props.disableMultipleColumnsSorting)); return (0, _extends2.default)({}, params, { callbacks: [...params.callbacks, apiRef.current.applySorting] }); }, [apiRef, props.disableMultipleColumnsSorting]); const flatSortingMethod = React.useCallback(params => { const rowTree = (0, _rows.gridRowTreeSelector)(apiRef); if (!params.sortRowList) { const bodyRowIds = []; const footerRowIds = []; (0, _rows.gridRowIdsSelector)(apiRef).forEach(rowId => { if (rowTree[rowId].isPinned) { return; } if (rowTree[rowId].position === 'footer') { footerRowIds.push(rowId); } else { bodyRowIds.push(rowId); } }); return [...bodyRowIds, ...footerRowIds]; } const bodyRows = []; const footerRowIds = []; Object.values(rowTree).forEach(rowNode => { if (rowNode.isPinned) { return; } if (rowNode.position === 'footer') { footerRowIds.push(rowNode.id); } else { bodyRows.push(rowNode); } }); return [...params.sortRowList(bodyRows), ...footerRowIds]; }, [apiRef]); (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'exportState', stateExportPreProcessing); (0, _pipeProcessing.useGridRegisterPipeProcessor)(apiRef, 'restoreState', stateRestorePreProcessing); (0, _strategyProcessing.useGridRegisterStrategyProcessor)(apiRef, _strategyProcessing.GRID_DEFAULT_STRATEGY, 'sorting', flatSortingMethod); /** * EVENTS */ const handleColumnHeaderClick = React.useCallback(({ colDef }, event) => { const allowMultipleSorting = event.shiftKey || event.metaKey || event.ctrlKey; sortColumn(colDef, undefined, allowMultipleSorting); }, [sortColumn]); const handleColumnHeaderKeyDown = React.useCallback(({ colDef }, event) => { // Ctrl + Enter opens the column menu if ((0, _keyboardUtils.isEnterKey)(event.key) && !event.ctrlKey && !event.metaKey) { sortColumn(colDef, undefined, event.shiftKey); } }, [sortColumn]); const handleColumnsChange = React.useCallback(() => { // When the columns change we check that the sorted columns are still part of the dataset const sortModel = (0, _gridSortingSelector.gridSortModelSelector)(apiRef); const latestColumns = (0, _gridColumnsSelector.gridColumnLookupSelector)(apiRef); if (sortModel.length > 0) { const newModel = sortModel.filter(sortItem => latestColumns[sortItem.field]); if (newModel.length < sortModel.length) { apiRef.current.setSortModel(newModel); } } }, [apiRef]); const handleStrategyProcessorChange = React.useCallback(methodName => { if (methodName === 'sorting') { apiRef.current.applySorting(); } }, [apiRef]); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'columnHeaderClick', handleColumnHeaderClick); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'columnHeaderKeyDown', handleColumnHeaderKeyDown); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'rowsSet', apiRef.current.applySorting); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'columnsChange', handleColumnsChange); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'activeStrategyProcessorChange', handleStrategyProcessorChange); /** * 1ST RENDER */ (0, _useFirstRender.useFirstRender)(() => { apiRef.current.applySorting(); }); /** * EFFECTS */ React.useEffect(() => { if (props.sortModel !== undefined) { apiRef.current.setSortModel(props.sortModel); } }, [apiRef, props.sortModel]); }; exports.useGridSorting = useGridSorting;