handle table row indexing with group rows

This commit is contained in:
jeffvli
2025-11-17 21:57:01 -08:00
parent 8433ce7f3e
commit fd85f1f51a
2 changed files with 69 additions and 7 deletions
@@ -29,7 +29,19 @@ export const RowIndexColumn = (props: ItemTableListInnerColumn) => {
}; };
const DefaultRowIndexColumn = (props: ItemTableListInnerColumn) => { const DefaultRowIndexColumn = (props: ItemTableListInnerColumn) => {
const { controls, enableExpansion } = props; const {
adjustedRowIndexMap,
controls,
data,
enableExpansion,
enableHeader,
internalState,
itemType,
rowIndex,
} = props;
const adjustedRowIndex =
adjustedRowIndexMap?.get(rowIndex) ?? (enableHeader ? rowIndex : rowIndex + 1);
if (enableExpansion) { if (enableExpansion) {
return ( return (
@@ -41,28 +53,32 @@ const DefaultRowIndexColumn = (props: ItemTableListInnerColumn) => {
onClick={(e) => onClick={(e) =>
controls.onExpand?.({ controls.onExpand?.({
event: e, event: e,
internalState: props.internalState, internalState,
item: props.data[props.rowIndex] as ItemListItem, item: data[rowIndex] as ItemListItem,
itemType: props.itemType, itemType,
}) })
} }
size="xs" size="xs"
variant="subtle" variant="subtle"
/> />
<Text className="hide-on-hover" isMuted isNoSelect> <Text className="hide-on-hover" isMuted isNoSelect>
{props.rowIndex} {adjustedRowIndex}
</Text> </Text>
</TableColumnContainer> </TableColumnContainer>
); );
} }
return <TableColumnTextContainer {...props}>{props.rowIndex}</TableColumnTextContainer>; return <TableColumnTextContainer {...props}>{adjustedRowIndex}</TableColumnTextContainer>;
}; };
const QueueSongRowIndexColumn = (props: ItemTableListInnerColumn) => { const QueueSongRowIndexColumn = (props: ItemTableListInnerColumn) => {
const status = usePlayerStatus(); const status = usePlayerStatus();
const { isActive } = useIsCurrentSong(props.data[props.rowIndex] as QueueSong); const { isActive } = useIsCurrentSong(props.data[props.rowIndex] as QueueSong);
const adjustedRowIndex =
props.adjustedRowIndexMap?.get(props.rowIndex) ??
(props.enableHeader ? props.rowIndex : props.rowIndex + 1);
return ( return (
<TableColumnTextContainer {...props}> <TableColumnTextContainer {...props}>
{isActive ? ( {isActive ? (
@@ -76,7 +92,7 @@ const QueueSongRowIndexColumn = (props: ItemTableListInnerColumn) => {
</Flex> </Flex>
) )
) : ( ) : (
props.rowIndex adjustedRowIndex
)} )}
</TableColumnTextContainer> </TableColumnTextContainer>
); );
@@ -226,8 +226,52 @@ const VirtualizedTableGrid = React.memo(
return result; return result;
}, [data, enableHeader, groups]); }, [data, enableHeader, groups]);
const adjustedRowIndexMap = useMemo(() => {
const map = new Map<number, number>();
if (!groups || groups.length === 0) {
const startIndex = enableHeader ? 1 : 0;
const endIndex = enableHeader ? dataWithGroups.length : dataWithGroups.length;
for (let rowIndex = startIndex; rowIndex < endIndex; rowIndex++) {
map.set(rowIndex, enableHeader ? rowIndex : rowIndex + 1);
}
return map;
}
const groupIndexes: number[] = [];
let cumulativeDataIndex = 0;
const headerOffset = enableHeader ? 1 : 0;
groups.forEach((group, groupIndex) => {
const groupHeaderIndex = headerOffset + cumulativeDataIndex + groupIndex;
groupIndexes.push(groupHeaderIndex);
cumulativeDataIndex += group.itemCount;
});
let adjustedIndex = 1;
const startIndex = enableHeader ? 0 : 0;
const endIndex = dataWithGroups.length;
for (let rowIndex = startIndex; rowIndex < endIndex; rowIndex++) {
if (enableHeader && rowIndex === 0) {
// Header row
map.set(rowIndex, 0);
} else if (groupIndexes.includes(rowIndex)) {
// Group header row - don't increment adjustedIndex
map.set(rowIndex, 0);
} else {
// Data row
map.set(rowIndex, adjustedIndex);
adjustedIndex++;
}
}
return map;
}, [dataWithGroups, enableHeader, groups]);
const itemProps: TableItemProps = useMemo( const itemProps: TableItemProps = useMemo(
() => ({ () => ({
adjustedRowIndexMap,
calculatedColumnWidths, calculatedColumnWidths,
cellPadding, cellPadding,
columns: parsedColumns, columns: parsedColumns,
@@ -256,6 +300,7 @@ const VirtualizedTableGrid = React.memo(
tableId, tableId,
}), }),
[ [
adjustedRowIndexMap,
calculatedColumnWidths, calculatedColumnWidths,
cellPadding, cellPadding,
controls, controls,
@@ -577,6 +622,7 @@ export interface TableGroupHeader {
} }
export interface TableItemProps { export interface TableItemProps {
adjustedRowIndexMap?: Map<number, number>; // Maps rowIndex to adjustedRowIndex (1-indexed, excluding group rows)
calculatedColumnWidths?: number[]; calculatedColumnWidths?: number[];
cellPadding?: ItemTableListProps['cellPadding']; cellPadding?: ItemTableListProps['cellPadding'];
columns: ItemTableListColumnConfig[]; columns: ItemTableListColumnConfig[];