Skip to content

Commit

Permalink
Merge pull request #58 from bryanmylee/feat/addFlatten
Browse files Browse the repository at this point in the history
Allow flattening of rows
  • Loading branch information
bryanmylee committed Sep 28, 2022
2 parents f8dfe31 + 317130b commit 3f00ac2
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 1 deletion.
117 changes: 117 additions & 0 deletions src/lib/plugins/addFlatten.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { createTable } from '$lib/createTable';
import type { Sample } from 'src/routes/_createSamples';
import { get, readable } from 'svelte/store';
import { addFlatten } from './addFlatten';
import { addSubRows } from './addSubRows';

const data = readable<Sample[]>([
{
firstName: 'Adam',
lastName: 'Lee',
age: 30,
progress: 30,
status: 'single',
visits: 5,
children: [
{
firstName: 'Allie',
lastName: 'Lee',
age: 30,
progress: 30,
status: 'single',
visits: 5,
children: [
{
firstName: 'Aria',
lastName: 'Lee',
age: 30,
progress: 30,
status: 'single',
visits: 5,
},
],
},
{ firstName: 'Amy', lastName: 'Lee', age: 30, progress: 30, status: 'single', visits: 5 },
],
},
{
firstName: 'Bryan',
lastName: 'Lee',
age: 30,
progress: 30,
status: 'single',
visits: 5,
children: [
{ firstName: 'Ben', lastName: 'Lee', age: 30, progress: 30, status: 'single', visits: 5 },
{ firstName: 'Beth', lastName: 'Lee', age: 30, progress: 30, status: 'single', visits: 5 },
],
},
{
firstName: 'Charlie',
lastName: 'Puth',
age: 30,
progress: 30,
status: 'single',
visits: 5,
children: [
{ firstName: 'Cory', lastName: 'Puth', age: 30, progress: 30, status: 'single', visits: 5 },
{
firstName: 'Carmen',
lastName: 'Puth',
age: 30,
progress: 30,
status: 'single',
visits: 5,
},
],
},
{ firstName: 'Danny', lastName: 'Lee', age: 40, progress: 40, status: 'single', visits: 5 },
{ firstName: 'Elliot', lastName: 'Page', age: 40, progress: 40, status: 'single', visits: 5 },
]);

test('basic row flattening', () => {
const table = createTable(data, {
sub: addSubRows({ children: 'children' }),
flatten: addFlatten({ initialDepth: 1 }),
});
const columns = table.createColumns([
table.column({
accessor: 'firstName',
header: 'First Name',
}),
table.column({
accessor: 'lastName',
header: 'Last Name',
}),
]);
const vm = table.createViewModel(columns);
const rows = get(vm.rows);
expect(rows).toHaveLength(6);
const row0 = rows[0].isData() ? rows[0] : undefined;
expect(row0).not.toBeUndefined();
expect(row0?.original.firstName).toBe('Allie');
expect(row0?.subRows).toHaveLength(1);
});

test('multi-level row flattening', () => {
const table = createTable(data, {
sub: addSubRows({ children: 'children' }),
flatten: addFlatten({ initialDepth: 2 }),
});
const columns = table.createColumns([
table.column({
accessor: 'firstName',
header: 'First Name',
}),
table.column({
accessor: 'lastName',
header: 'Last Name',
}),
]);
const vm = table.createViewModel(columns);
const rows = get(vm.rows);
expect(rows).toHaveLength(1);
const row0 = rows[0].isData() ? rows[0] : undefined;
expect(row0).not.toBeUndefined();
expect(row0?.original.firstName).toBe('Aria');
});
69 changes: 69 additions & 0 deletions src/lib/plugins/addFlatten.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import type { BodyRow } from '$lib/bodyRows';
import type { DeriveRowsFn, NewTablePropSet, TablePlugin } from '$lib/types/TablePlugin';
import { derived, writable, type Readable, type Writable } from 'svelte/store';

export interface FlattenConfig {
initialDepth?: number;
}

export interface FlattenState {
depth: Writable<number>;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-interface
export interface FlattenColumnOptions<Item> {}

export type FlattenPropSet = NewTablePropSet<{
'tbody.tr.td': {
flatten: (depth: number) => void;
unflatten: () => void;
};
}>;

export const getFlattenedRows = <Item, Row extends BodyRow<Item>>(
rows: Row[],
depth: number
): Row[] => {
if (depth === 0) return rows;
const flattenedRows: Row[] = [];
for (const row of rows) {
if (row.subRows === undefined) continue;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
flattenedRows.push(...(getFlattenedRows(row.subRows as any, depth - 1) as Row[]));
}
return flattenedRows;
};

export const addFlatten =
<Item>({ initialDepth = 0 }: FlattenConfig = {}): TablePlugin<
Item,
FlattenState,
FlattenColumnOptions<Item>,
FlattenPropSet
> =>
() => {
const depth = writable(initialDepth);
const pluginState: FlattenState = { depth };
const deriveRows: DeriveRowsFn<Item> = (rows) => {
return derived([rows, depth], ([$rows, $depth]) => {
return getFlattenedRows<Item, typeof $rows[number]>($rows, $depth);
});
};

return {
pluginState,
deriveRows,
hooks: {
'tbody.tr.td': () => {
const props: Readable<FlattenPropSet['tbody.tr.td']> = derived([], () => {
const flatten = ($depth: number) => {
depth.set($depth);
};
const unflatten = () => flatten(0);
return { flatten, unflatten };
});
return { props };
},
},
};
};
2 changes: 1 addition & 1 deletion src/lib/plugins/addGroupBy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ test('basic row grouping', () => {
expect(subRow12Data.firstName).toBe('Danny');
});

it.only('preserves subrows of a row after grouping', () => {
it('preserves subrows of a row after grouping', () => {
const data = readable<Sample[]>([
{
firstName: 'Adam',
Expand Down

1 comment on commit 3f00ac2

@vercel
Copy link

@vercel vercel bot commented on 3f00ac2 Sep 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.