Skip to content

Commit

Permalink
Merge pull request #127 from fhlavac/selected
Browse files Browse the repository at this point in the history
Fix tree table data selection
  • Loading branch information
fhlavac authored Nov 11, 2024
2 parents 995b46b + cf91764 commit e122f5f
Showing 1 changed file with 39 additions and 18 deletions.
57 changes: 39 additions & 18 deletions packages/module/src/DataViewTableTree/DataViewTableTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,45 @@ import { DataViewTableHead } from '../DataViewTableHead';
import { DataViewTh, DataViewTrTree, isDataViewTdObject } from '../DataViewTable';
import { DataViewState } from '../DataView/DataView';

const getDescendants = (node: DataViewTrTree): DataViewTrTree[] => (!node.children || !node.children.length) ? [ node ] : node.children.flatMap(getDescendants);

const isNodeChecked = (node: DataViewTrTree, isSelected: (node: DataViewTrTree) => boolean) => {
let allSelected = true;
let someSelected = false;

for (const descendant of getDescendants(node)) {
const selected = !!isSelected?.(descendant);

someSelected ||= selected;
allSelected &&= selected;

if (!allSelected && someSelected) { return null }
}

return allSelected;
const getNodesAffectedBySelection = (
allRows: DataViewTrTree[],
node: DataViewTrTree,
isChecking: boolean,
isSelected?: (item: DataViewTrTree) => boolean
): DataViewTrTree[] => {

const getDescendants = (node: DataViewTrTree): DataViewTrTree[] =>
node.children ? node.children.flatMap(getDescendants).concat(node) : [ node ];

const findParent = (child: DataViewTrTree, rows: DataViewTrTree[]): DataViewTrTree | undefined =>
rows.find(row => row.children?.some(c => c === child)) ??
rows.flatMap(row => row.children ?? []).map(c => findParent(child, [ c ])).find(p => p);

const getAncestors = (node: DataViewTrTree): DataViewTrTree[] => {
const ancestors: DataViewTrTree[] = [];
let parent = findParent(node, allRows);
while (parent) {
ancestors.push(parent);
parent = findParent(parent, allRows);
}
return ancestors;
};

const affectedNodes = new Set([ node, ...getDescendants(node) ]);

getAncestors(node).forEach(ancestor => {
const allChildrenSelected = ancestor.children?.every(child => isSelected?.(child) || affectedNodes.has(child));
const anyChildAffected = ancestor.children?.some(child => affectedNodes.has(child) || child.id === node.id);

if (isChecking ? !isSelected?.(ancestor) && allChildrenSelected : isSelected?.(ancestor) && anyChildAffected) {
affectedNodes.add(ancestor);
}
});

return Array.from(affectedNodes);
};


/** extends TableProps */
export interface DataViewTableTreeProps extends Omit<TableProps, 'onSelect' | 'rows'> {
/** Columns definition */
Expand Down Expand Up @@ -83,7 +104,7 @@ export const DataViewTableTree: React.FC<DataViewTableTreeProps> = ({
}
const isExpanded = expandedNodeIds.includes(node.id);
const isDetailsExpanded = expandedDetailsNodeNames.includes(node.id);
const isChecked = isSelected && isNodeChecked(node, isSelected);
const isChecked = isSelected?.(node);
let icon = leafIcon;
if (node.children) {
icon = isExpanded ? expandedIcon : collapsedIcon;
Expand All @@ -100,7 +121,7 @@ export const DataViewTableTree: React.FC<DataViewTableTreeProps> = ({
const otherDetailsExpandedNodeIds = prevDetailsExpanded.filter(id => id !== node.id);
return isDetailsExpanded ? otherDetailsExpandedNodeIds : [ ...otherDetailsExpandedNodeIds, node.id ];
}),
onCheckChange: (isSelectDisabled?.(node) || !onSelect) ? undefined : (_event, isChecking) => onSelect?.(isChecking, getDescendants(node)),
onCheckChange: (isSelectDisabled?.(node) || !onSelect) ? undefined : (_event, isChecking) => onSelect?.(isChecking, getNodesAffectedBySelection(rows, node, isChecking, isSelected)),
rowIndex,
props: {
isExpanded,
Expand Down

0 comments on commit e122f5f

Please sign in to comment.