Skip to content

Commit

Permalink
Tree/improve node selection & updating collapsed nodes (#259)
Browse files Browse the repository at this point in the history
fixes #258 and #257
  • Loading branch information
radubrehar authored Nov 1, 2024
1 parent 06c6cb6 commit e7aaab5
Show file tree
Hide file tree
Showing 47 changed files with 1,699 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ export default test.describe.parallel('Table', () => {

expect(count).toEqual(12);

const expanderIcon = await page.$('.InfiniteIcon-expander--expanded');
const expanderIcon = await page.$(
'.InfiniteIcon-expand-collapse--expanded',
);

// collapse Cuba
await expanderIcon!.click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default test.describe.parallel('hideEmptyGroupColumns', () => {
'department',
]);

await page.click(`[data-name="expander-icon"]`);
await page.click(`[data-name="expand-collapse-icon"]`);

await page.waitForTimeout(50);
ids = await getHeaderColumnIds({ page });
Expand All @@ -45,7 +45,7 @@ export default test.describe.parallel('hideEmptyGroupColumns', () => {
'department',
]);

await page.click(`[data-name="expander-icon"]`);
await page.click(`[data-name="expand-collapse-icon"]`);

await page.waitForTimeout(50);
ids = await getHeaderColumnIds({ page });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default test.describe.parallel('hideEmptyGroupColumns', () => {
'department',
]);

await page.click(`[data-name="expander-icon"]`);
await page.click(`[data-name="expand-collapse-icon"]`);

await page.waitForTimeout(50);
ids = await columnModel.getVisibleColumnIds();
Expand Down Expand Up @@ -45,7 +45,7 @@ export default test.describe.parallel('hideEmptyGroupColumns', () => {
'department',
]);

await page.click(`[data-name="expander-icon"]`);
await page.click(`[data-name="expand-collapse-icon"]`);

await page.waitForTimeout(50);
ids = await columnModel.getVisibleColumnIds();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ async function getRowGroupNesting(rowIndex: number, page: Page) {
const cell = getCellNodeLocator({ colIndex: 0, rowIndex }, { page });

return await cell
.locator('svg[data-name="expander-icon"]')
.locator('svg[data-name="expand-collapse-icon"]')
.evaluate(
(node) => getComputedStyle(node.parentElement!).paddingInlineStart,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default test.describe('Default tree icon', () => {
await page.waitForInfinite();

async function getInfo() {
const icons = await page.$$('[data-name="expander-icon"]');
const icons = await page.$$('[data-name="expand-collapse-icon"]');

return Promise.all(
icons.map(async (icon) => {
Expand Down
145 changes: 145 additions & 0 deletions examples/src/pages/tests/table/treegrid/empty-children.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import * as React from 'react';

import {
DataSourceApi,
InfiniteTableColumn,
TreeDataSource,
TreeGrid,
} from '@infinite-table/infinite-react';

export type FileSystemNode = {
name: string;
type: 'file' | 'folder';
children?: FileSystemNode[] | null;
sizeKB?: number;
id: string;
collapsed?: boolean;
};

export const nodes: FileSystemNode[] = [
{
name: 'Documents',
type: 'folder',
id: '1',
children: [
{
name: 'report.doc',
type: 'file',
sizeKB: 100,
id: '2',
},
{
type: 'folder',
name: 'pictures',
id: '3',
children: [],
},
{
type: 'folder',
name: 'diverse',
id: '4',
children: [
{
name: 'beach.jpg',
type: 'file',
sizeKB: 2024,
id: '6',
},
],
},
],
},
];

const columns: Record<string, InfiniteTableColumn<FileSystemNode>> = {
name: {
field: 'name',
renderTreeIcon: ({ rowInfo }) => {
if (!rowInfo.isParentNode) {
return null;
}
return (
<div
style={{
display: 'inline-block',
width: 24,
}}
>
{rowInfo.nodeExpanded ? '👇' : '👉'}
</div>
);
},
renderSelectionCheckBox: true,
renderValue: ({ value, data }) => {
return (
<>
{value} - {data!.id}
</>
);
},
},
type: { field: 'type' },
sizeKB: { field: 'sizeKB' },
};

export default function DataTestPage() {
const [dataSourceApi, setDataSourceApi] =
React.useState<DataSourceApi<FileSystemNode> | null>(null);
return (
<React.StrictMode>
<div className="flex flex-col gap-2 bg-black justify-start p-10">
<button
className="bg-white text-black p-2"
onClick={() => {
dataSourceApi!.updateData({
id: '3',
children: undefined,
});
dataSourceApi!.insertDataArray(
[
{
id: 'x',
name: 'x',
type: 'file',
},
{
id: 'y',
name: 'y',
type: 'file',
},
],
{
position: 'before',
primaryKey: '6',
},
);
}}
>
Update
</button>
<TreeDataSource<FileSystemNode>
onReady={setDataSourceApi}
data={nodes}
debugMode
primaryKey="id"
nodesKey="children"
selectionMode="multi-row"
>
<TreeGrid<FileSystemNode>
wrapRowsHorizontally
domProps={{
style: {
margin: '5px',
height: '80vh',
border: '1px solid gray',
position: 'relative',
},
}}
columns={columns}
columnDefaultWidth={250}
/>
</TreeDataSource>
</div>
</React.StrictMode>
);
}
95 changes: 95 additions & 0 deletions examples/src/pages/tests/table/treegrid/is-node-read-only.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import * as React from 'react';

import {
InfiniteTableColumn,
TreeDataSource,
TreeGrid,
} from '@infinite-table/infinite-react';

export type FileSystemNode = {
name: string;
type: 'file' | 'folder';
children?: FileSystemNode[] | null;
sizeKB?: number;
id: string;
collapsed?: boolean;
};

export const nodes: FileSystemNode[] = [
{
name: 'Documents',
type: 'folder',
id: '1',
children: [
{
name: 'report.doc',
type: 'file',
sizeKB: 100,
id: '2',
},
{
type: 'folder',
name: 'pictures',
id: '3',
children: [
{
name: 'mountain.jpg',
type: 'file',
sizeKB: 302,
id: '5',
},
],
},

{
type: 'file',
name: 'last.txt',
id: '7',
},
],
},
];

const columns: Record<string, InfiniteTableColumn<FileSystemNode>> = {
name: {
field: 'name',
renderTreeIcon: true,
renderValue: ({ value, data }) => {
return (
<>
{value} - {data!.id}
</>
);
},
},
type: { field: 'type' },
sizeKB: { field: 'sizeKB' },
};

export default function DataTestPage() {
return (
<React.StrictMode>
<TreeDataSource<FileSystemNode>
data={nodes}
primaryKey="id"
isNodeReadOnly={(rowInfo) => rowInfo.data.id === '1'}
defaultTreeExpandState={{
defaultExpanded: true,
collapsedPaths: [['1']],
}}
>
<TreeGrid<FileSystemNode>
domProps={{
style: {
margin: '5px',
height: 900,
border: '1px solid gray',
position: 'relative',
},
}}
columns={columns}
/>
</TreeDataSource>
</React.StrictMode>
);
}
26 changes: 26 additions & 0 deletions examples/src/pages/tests/table/treegrid/is-node-read-only.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { test, expect } from '@testing';

export default test.describe('isNodeReadOnly', () => {
test('should work ', async ({ page, rowModel, treeModel, apiModel }) => {
await page.waitForInfinite();

expect(await rowModel.getRenderedRowCount()).toBe(1);

await treeModel.toggleParentNode(0);

expect(await rowModel.getRenderedRowCount()).toBe(1);

await apiModel.evaluateDataSource((api) => {
api.treeApi.toggleNode(['1']);
});

expect(await rowModel.getRenderedRowCount()).toBe(1);

// force: true should be respected
await apiModel.evaluateDataSource((api) => {
api.treeApi.toggleNode(['1'], { force: true });
});

expect(await rowModel.getRenderedRowCount()).toBe(5);
});
});
Loading

0 comments on commit e7aaab5

Please sign in to comment.