UNPKG

@mui/x-data-grid-pro

Version:

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

191 lines (180 loc) 6.08 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import { GRID_ROOT_GROUP_ID } from '@mui/x-data-grid'; export const getGroupRowIdFromPath = path => { const pathStr = path.map(groupingCriteria => `${groupingCriteria.field}/${groupingCriteria.key}`).join('-'); return `auto-generated-row-${pathStr}`; }; export const getNodePathInTree = ({ id, tree }) => { const path = []; let node = tree[id]; while (node.id !== GRID_ROOT_GROUP_ID) { path.push({ field: node.type === 'leaf' ? null : node.groupingField, key: node.groupingKey }); node = tree[node.parent]; } path.reverse(); return path; }; export const checkGroupChildrenExpansion = (node, defaultGroupingExpansionDepth, isGroupExpandedByDefault) => { let childrenExpanded; if (node.id === GRID_ROOT_GROUP_ID) { childrenExpanded = true; } else if (isGroupExpandedByDefault) { childrenExpanded = isGroupExpandedByDefault(node); } else { childrenExpanded = defaultGroupingExpansionDepth === -1 || defaultGroupingExpansionDepth > node.depth; } return childrenExpanded; }; export const updateGroupDefaultExpansion = (node, defaultGroupingExpansionDepth, isGroupExpandedByDefault) => { const childrenExpanded = checkGroupChildrenExpansion(node, defaultGroupingExpansionDepth, isGroupExpandedByDefault); node.childrenExpanded = childrenExpanded; return node; }; /** * Insert a node in the tree */ export const insertNodeInTree = (node, tree, treeDepths, previousTree) => { // 1. Insert node in the tree. tree[node.id] = node; // 2. Increment the `treeDepths` object for the node's depth. treeDepths[node.depth] = (treeDepths[node.depth] ?? 0) + 1; // 3. Register the new node in its parent. const parentNode = tree[node.parent]; if (node.type === 'group' || node.type === 'leaf') { // For groups and leaves, // Register the node from its parents `children` and `childrenFromPath` properties. const groupingFieldName = node.groupingField ?? '__no_field__'; const groupingKeyName = node.groupingKey ?? '__no_key__'; const groupingField = parentNode.childrenFromPath?.[groupingFieldName]; if (previousTree !== null && previousTree[parentNode.id] === tree[parentNode.id]) { parentNode.children = [...parentNode.children, node.id]; } else { parentNode.children.push(node.id); } if (groupingField == null) { parentNode.childrenFromPath[groupingFieldName] = { [groupingKeyName.toString()]: node.id }; } else { groupingField[groupingKeyName.toString()] = node.id; } } else if (node.type === 'footer') { // For footers, // Register the node from its parent `footerId` property. parentNode.footerId = node.id; } }; /** * Removes a node from the tree */ export const removeNodeFromTree = ({ node, tree, treeDepths }) => { // 1. Remove node from the tree. delete tree[node.id]; // 2. Decrement the `treeDepths` object for the node's depth. const nodeDepth = node.depth; const currentNodeCount = treeDepths[nodeDepth]; if (currentNodeCount === 1) { delete treeDepths[nodeDepth]; } else { treeDepths[nodeDepth] = currentNodeCount - 1; } // 3. Unregister the new node in its parent. const parentNode = tree[node.parent]; // For footers, // Unregister the node from its parent `footerId` property. if (node.type === 'footer') { tree[parentNode.id] = _extends({}, parentNode, { footerId: null }); } // For groups and leaves, // Unregister the node from its parents `children` and `childrenFromPath` properties. else { const groupingField = node.groupingField ?? '__no_field__'; const groupingKey = node.groupingKey ?? '__no_key__'; // TODO rows v6: Can we avoid this linear complexity ? const children = parentNode.children.filter(childId => childId !== node.id); const childrenFromPath = parentNode.childrenFromPath; delete childrenFromPath[groupingField][groupingKey.toString()]; tree[parentNode.id] = _extends({}, parentNode, { children, childrenFromPath }); } }; /** * Updates the `id` and `isAutoGenerated` properties of a group node. */ export const updateGroupNodeIdAndAutoGenerated = ({ node, updatedNode, previousTree, tree, treeDepths }) => { // 1. Set the new parent for all children from the old group node.children.forEach(childId => { tree[childId] = _extends({}, tree[childId], { parent: updatedNode.id }); }); // 2. Remove the old group from the tree removeNodeFromTree({ node, tree, treeDepths }); // 3. Add the new group in the tree const groupNode = _extends({}, node, updatedNode); insertNodeInTree(groupNode, tree, treeDepths, previousTree); }; export const createUpdatedGroupsManager = () => ({ value: {}, addAction(groupId, action) { if (!this.value[groupId]) { this.value[groupId] = {}; } this.value[groupId][action] = true; } }); export const getVisibleRowsLookup = ({ tree, filteredRowsLookup }) => { if (!filteredRowsLookup) { return {}; } const visibleRowsLookup = {}; const handleTreeNode = (node, areAncestorsExpanded) => { const isPassingFiltering = filteredRowsLookup[node.id]; if (node.type === 'group') { node.children.forEach(childId => { const childNode = tree[childId]; handleTreeNode(childNode, areAncestorsExpanded && !!node.childrenExpanded); }); } visibleRowsLookup[node.id] = isPassingFiltering && areAncestorsExpanded; // TODO rows v6: Should we keep storing the visibility status of footer independently or rely on the group visibility in the selector ? if (node.type === 'group' && node.footerId != null) { visibleRowsLookup[node.footerId] = isPassingFiltering && areAncestorsExpanded && !!node.childrenExpanded; } }; const nodes = Object.values(tree); for (let i = 0; i < nodes.length; i += 1) { const node = nodes[i]; if (node.depth === 0) { handleTreeNode(node, true); } } return visibleRowsLookup; };