@mui/x-data-grid
Version:
The Community plan edition of the Data Grid components (MUI X).
82 lines (80 loc) • 3.54 kB
JavaScript
import { isDeepEqual } from '@mui/x-internals/isDeepEqual';
import { isLeaf } from "../../../models/gridColumnGrouping.js";
// This is the recurrence function that help writing `unwrapGroupingColumnModel()`
const recurrentUnwrapGroupingColumnModel = (columnGroupNode, parents, unwrappedGroupingModelToComplete) => {
if (isLeaf(columnGroupNode)) {
if (unwrappedGroupingModelToComplete[columnGroupNode.field] !== undefined) {
throw new Error([`MUI X: columnGroupingModel contains duplicated field`, `column field ${columnGroupNode.field} occurs two times in the grouping model:`, `- ${unwrappedGroupingModelToComplete[columnGroupNode.field].join(' > ')}`, `- ${parents.join(' > ')}`].join('\n'));
}
unwrappedGroupingModelToComplete[columnGroupNode.field] = parents;
return;
}
const {
groupId,
children
} = columnGroupNode;
children.forEach(child => {
recurrentUnwrapGroupingColumnModel(child, [...parents, groupId], unwrappedGroupingModelToComplete);
});
};
/**
* 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;
};
export const getColumnGroupsHeaderStructure = (orderedColumns, unwrappedGroupingModel, pinnedFields) => {
const getParents = field => unwrappedGroupingModel[field] ?? [];
const groupingHeaderStructure = [];
const maxDepth = Math.max(...orderedColumns.map(field => getParents(field).length));
const haveSameParents = (field1, field2, depth) => isDeepEqual(getParents(field1).slice(0, depth + 1), getParents(field2).slice(0, depth + 1));
const haveDifferentContainers = (field1, field2) => {
if (pinnedFields?.left && pinnedFields.left.includes(field1) && !pinnedFields.left.includes(field2)) {
return true;
}
if (pinnedFields?.right && !pinnedFields.right.includes(field1) && pinnedFields.right.includes(field2)) {
return true;
}
return false;
};
for (let depth = 0; depth < maxDepth; depth += 1) {
const depthStructure = orderedColumns.reduce((structure, newField) => {
const groupId = getParents(newField)[depth] ?? null;
if (structure.length === 0) {
return [{
columnFields: [newField],
groupId
}];
}
const lastGroup = structure[structure.length - 1];
const prevField = lastGroup.columnFields[lastGroup.columnFields.length - 1];
const prevGroupId = lastGroup.groupId;
if (prevGroupId !== groupId || !haveSameParents(prevField, newField, depth) ||
// Fix for https://github.com/mui/mui-x/issues/7041
haveDifferentContainers(prevField, newField)) {
// It's a new group
return [...structure, {
columnFields: [newField],
groupId
}];
}
// It extends the previous group
return [...structure.slice(0, structure.length - 1), {
columnFields: [...lastGroup.columnFields, newField],
groupId
}];
}, []);
groupingHeaderStructure.push(depthStructure);
}
return groupingHeaderStructure;
};