UNPKG

@mui/x-data-grid

Version:

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

153 lines (130 loc) 5.47 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; const _excluded = ["groupId", "children"]; import * as React from 'react'; import { isLeaf } from '../../../models/gridColumnGrouping'; import { gridColumnGroupsLookupSelector } from './gridColumnGroupsSelector'; import { gridColumnLookupSelector } from '../columns/gridColumnsSelector'; import { useGridApiMethod } from '../../utils/useGridApiMethod'; export function hasGroupPath(lookupElement) { return lookupElement.groupPath !== undefined; } // This is the recurrence function that help writing `unwrapGroupingColumnModel()` const recurrentUnwrapGroupingColumnModel = (columnGroupNode, parents, unwrappedGroupingModelToComplet) => { if (isLeaf(columnGroupNode)) { if (unwrappedGroupingModelToComplet[columnGroupNode.field] !== undefined) { throw new Error([`MUI: columnGroupingModel contains duplicated field`, `column field ${columnGroupNode.field} occurrs two times in the grouping model:`, `- ${unwrappedGroupingModelToComplet[columnGroupNode.field].join(' > ')}`, `- ${parents.join(' > ')}`].join('\n')); } unwrappedGroupingModelToComplet[columnGroupNode.field] = parents; return; } const { groupId, children } = columnGroupNode; children.forEach(child => { recurrentUnwrapGroupingColumnModel(child, [...parents, groupId], unwrappedGroupingModelToComplet); }); }; /** * This is a function that provide for each column the array of its parents. * Parents are ordered from the root to the leaf. * @param columnGroupingModel The model such as provided in DataGrid props * @returns An object `{[field]: groupIds}` where `groupIds` is the parents of the column `field` */ export const unwrapGroupingColumnModel = columnGroupingModel => { if (!columnGroupingModel) { return {}; } const unwrappedSubTree = {}; columnGroupingModel.forEach(columnGroupNode => { recurrentUnwrapGroupingColumnModel(columnGroupNode, [], unwrappedSubTree); }); return unwrappedSubTree; }; const createGroupLookup = columnGroupingModel => { let groupLookup = {}; columnGroupingModel.forEach(node => { if (isLeaf(node)) { return; } const { groupId, children } = node, other = _objectWithoutPropertiesLoose(node, _excluded); if (!groupId) { throw new Error('MUI: An element of the columnGroupingModel does not have either `field` or `groupId`.'); } if (!children) { console.warn(`MUI: group groupId=${groupId} has no children.`); } const groupParam = _extends({}, other, { groupId }); const subTreeLookup = createGroupLookup(children); if (subTreeLookup[groupId] !== undefined || groupLookup[groupId] !== undefined) { throw new Error(`MUI: The groupId ${groupId} is used multiple times in the columnGroupingModel.`); } groupLookup = _extends({}, groupLookup, subTreeLookup, { [groupId]: groupParam }); }); return _extends({}, groupLookup); }; export const columnGroupsStateInitializer = (state, props) => { var _props$columnGrouping; const groupLookup = createGroupLookup((_props$columnGrouping = props.columnGroupingModel) != null ? _props$columnGrouping : []); return _extends({}, state, { columnGrouping: { lookup: groupLookup, groupCollapsedModel: {} } }); }; /** * @requires useGridColumns (method, event) * @requires useGridParamsApi (method) */ export const useGridColumnGrouping = (apiRef, props) => { var _props$experimentalFe2; /** * API METHODS */ const getColumnGroupPath = React.useCallback(field => { var _columnLookup$field$g, _columnLookup$field; const columnLookup = gridColumnLookupSelector(apiRef); return (_columnLookup$field$g = (_columnLookup$field = columnLookup[field]) == null ? void 0 : _columnLookup$field.groupPath) != null ? _columnLookup$field$g : []; }, [apiRef]); const getAllGroupDetails = React.useCallback(() => { const columnGroupLookup = gridColumnGroupsLookupSelector(apiRef); return columnGroupLookup; }, [apiRef]); const columnGroupingApi = { unstable_getColumnGroupPath: getColumnGroupPath, unstable_getAllGroupDetails: getAllGroupDetails }; useGridApiMethod(apiRef, columnGroupingApi, 'GridColumnGroupingApi'); /** * EFFECTS */ // The effect does not track any value defined synchronously during the 1st render by hooks called after `useGridColumns` // As a consequence, the state generated by the 1st run of this useEffect will always be equal to the initialization one const isFirstRender = React.useRef(true); React.useEffect(() => { var _props$experimentalFe, _props$columnGrouping2; if (isFirstRender.current) { isFirstRender.current = false; return; } if (!((_props$experimentalFe = props.experimentalFeatures) != null && _props$experimentalFe.columnGrouping)) { return; } const groupLookup = createGroupLookup((_props$columnGrouping2 = props.columnGroupingModel) != null ? _props$columnGrouping2 : []); apiRef.current.setState(state => _extends({}, state, { columnGrouping: _extends({}, state.columnGrouping, { lookup: groupLookup }) })); }, [apiRef, props.columnGroupingModel, (_props$experimentalFe2 = props.experimentalFeatures) == null ? void 0 : _props$experimentalFe2.columnGrouping]); };