Skip to content

Commit

Permalink
minor type fixing and release version patch
Browse files Browse the repository at this point in the history
  • Loading branch information
radubrehar committed Jul 24, 2024
1 parent 743ccdd commit 4ec13d7
Show file tree
Hide file tree
Showing 6 changed files with 336 additions and 14 deletions.
2 changes: 1 addition & 1 deletion source/src/components/DataSource/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ export type DataSourceProps<T> = {
groupRowsState?: GroupRowsState | DataSourcePropGroupRowsStateObject<any>;
defaultGroupRowsState?:
| GroupRowsState
| DataSourcePropGroupRowsStateObject<keyof T>;
| DataSourcePropGroupRowsStateObject<any>;
onGroupRowsStateChange?: (groupRowsState: GroupRowsState) => void;

collapseGroupRowsOnDataFunctionChange?: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import {
InfiniteTable,
DataSource,
DataSourceData,
InfiniteTablePropColumns,
DataSourceProps,
} from '@infinite-table/infinite-react';
import * as React from 'react';
import { useMemo } from 'react';

type Developer = {
id: number;
firstName: string;
lastName: string;
country: string;
city: string;
currency: string;
preferredLanguage: string;
stack: string;
canDesign: 'yes' | 'no';
hobby: string;
salary: number;
age: number;
};

const columns: InfiniteTablePropColumns<Developer> = {
country: { field: 'country', header: 'Country' },
id: { field: 'id', header: 'ID', defaultWidth: 100 },
salary: {
field: 'salary',
header: 'Salary',
renderValue: ({ value, rowInfo }) => {
if (rowInfo.isGroupRow) {
return (
<>
Avg: <b>{value}</b>
</>
);
}
return value;
},
},
age: { field: 'age', header: 'Age' },
firstName: { field: 'firstName', header: 'First Name' },
preferredLanguage: {
field: 'preferredLanguage',
header: 'Preferred Language',
},
lastName: { field: 'lastName', header: 'Last Name' },

city: { field: 'city', header: 'City' },
currency: { field: 'currency', header: 'Currency' },
stack: { field: 'stack', header: 'Stack' },
canDesign: { field: 'canDesign', header: 'Can Design' },
hobby: { field: 'hobby', header: 'Hobby' },
};

const groupBy: DataSourceProps<Developer>['groupBy'] = [
{
field: 'country',
},
{
field: 'stack',
},
];

const aggregationReducers: DataSourceProps<Developer>['aggregationReducers'] = {
salary: {
field: 'salary',
reducer: 'avg',
},
};

export default function App() {
const lazyLoad = useMemo(() => ({ batchSize: 40 }), []);
return (
<DataSource<Developer>
data={dataSource}
primaryKey="id"
groupBy={groupBy}
lazyLoad={lazyLoad}
aggregationReducers={aggregationReducers}
>
<InfiniteTable<Developer>
columns={columns}
columnDefaultWidth={130}
groupColumn={{
id: 'group-col',
defaultSortable: false,
}}
groupRenderStrategy="single-column"
/>
</DataSource>
);
}

const dataSource: DataSourceData<Developer> = ({
pivotBy,
aggregationReducers,
groupBy,

lazyLoadStartIndex,
lazyLoadBatchSize,
groupRowsState,
groupKeys = [],
sortInfo,
}) => {
if (sortInfo && !Array.isArray(sortInfo)) {
sortInfo = [sortInfo];
}
const startLimit: string[] = [];
if (lazyLoadBatchSize && lazyLoadBatchSize > 0) {
const start = lazyLoadStartIndex || 0;
startLimit.push(`start=${start}`);
startLimit.push(`limit=${lazyLoadBatchSize}`);
}
const args = [
...startLimit,
pivotBy
? 'pivotBy=' + JSON.stringify(pivotBy.map((p) => ({ field: p.field })))
: null,
`groupKeys=${JSON.stringify(groupKeys)}`,
`prefetchGroupKeys=${JSON.stringify(groupRowsState?.expandedRows || [])}`,
groupBy
? 'groupBy=' + JSON.stringify(groupBy.map((p) => ({ field: p.field })))
: null,
sortInfo
? 'sortInfo=' +
JSON.stringify(
sortInfo.map((s) => ({
field: s.field,
dir: s.dir,
})),
)
: null,
aggregationReducers
? 'reducers=' +
JSON.stringify(
Object.keys(aggregationReducers).map((key) => ({
field: aggregationReducers[key].field,
id: key,
name: aggregationReducers[key].reducer,
})),
)
: null,
]
.filter(Boolean)
.join('&');
return fetch(
process.env.NEXT_PUBLIC_BASE_URL + `/developers10k-sql?` + args,
).then((r) => r.json());
};
29 changes: 28 additions & 1 deletion www/content/docs/learn/working-with-data/lazy-loading.page.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ We call this `"lazy loading"`, and it needs to be enabled by specifying the <Dat

<Note>

The <DataSourcePropLink name="lazyLoad">DataSource.lazyLoad</DataSourcePropLink> prop can be either a boolean or an object with a `batchSize: number` property. If `batchSize` is not specified, it will load all records from the current row group (makes sense for grouped and/or pivoted data). For ungrouped and unpivoted data, make sure you `batchSize` to a conveninent number.
The <DataSourcePropLink name="lazyLoad">DataSource.lazyLoad</DataSourcePropLink> prop can be either a boolean or an object with a `batchSize: number` property. If `batchSize` is not specified, it will load all records from the current row group (makes sense for grouped and/or pivoted data). For ungrouped and unpivoted data, make sure you set `batchSize` to a conveninent number.

Simply specifying `lazyLoad=true` makes more sense for grouped (or/and pivoted) data, where you want to load all records from the current level at once. If you want configure it this way, new data will only be requested when a group row is expanded.

Expand Down Expand Up @@ -50,3 +50,30 @@ Find out about server-side grouping
Find out about server-side pivoting
</YouWillLearnCard>
</HeroCards>

## How lazy loading fetches data

When lazy loading is enabled, and the <DPropLink name="sortInfo" /> changes (eg: user clicks on a column header), the DataGrid will discard current data and call the <DPropLink name="data" /> function prop again, to fetch the new data. The same happens when the <DPropLink name="filterValue" /> or <DPropLink name="groupBy" /> changes. This is done automatically by the component, and you don't need to do anything.

<Sandpack title="Lazy loading grouped data" viewMode="preview">

<Description>

This demo lazily loads grouped data as the user scrolls down. Expand some groups to see the lazy loading in action.

When the user stops scrolling, after <PropLink name="scrollStopDelay" /> milliseconds, the DataGrid will fetch the next batch of data from the server.

</Description>

```ts file="grouped-lazy-load-example.page.tsx"

```

</Sandpack>


<Note>

Batching also happens for groups - when a group is expanded, the DataGrid will fetch the first batch of data in the expanded group and then fetch additional batches as the user scrolls down. When scrolling goes beyound the group, the DataGrid is smart enough to request a batch of data from sibling groups.

</Note>
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,21 @@ type Developer = {
};

const columns: InfiniteTablePropColumns<Developer> = {
id: { field: 'id' },
salary: { field: 'salary' },
age: { field: 'age' },
firstName: { field: 'firstName' },
preferredLanguage: { field: 'preferredLanguage' },
lastName: { field: 'lastName' },
country: { field: 'country' },
city: { field: 'city' },
currency: { field: 'currency' },
stack: { field: 'stack' },
canDesign: { field: 'canDesign' },
id: { field: 'id', header: 'ID', defaultWidth: 100 },
salary: { field: 'salary', header: 'Salary' },
age: { field: 'age', header: 'Age' },
firstName: { field: 'firstName', header: 'First Name' },
preferredLanguage: {
field: 'preferredLanguage',
header: 'Preferred Language',
},
lastName: { field: 'lastName', header: 'Last Name' },
country: { field: 'country', header: 'Country' },
city: { field: 'city', header: 'City' },
currency: { field: 'currency', header: 'Currency' },
stack: { field: 'stack', header: 'Stack' },
canDesign: { field: 'canDesign', header: 'Can Design' },
hobby: { field: 'hobby', header: 'Hobby' },
};

export default function App() {
Expand All @@ -44,7 +48,7 @@ export default function App() {
primaryKey="id"
lazyLoad={lazyLoad}
>
<InfiniteTable<Developer> columns={columns} />
<InfiniteTable<Developer> columns={columns} columnDefaultWidth={130} />
</DataSource>
);
}
Expand Down
26 changes: 26 additions & 0 deletions www/content/docs/reference/infinite-table-props.page.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ The details for each city shows a DataGrid with developers in that city.

</Prop>

<Prop name="scrollStopDelay" type="number" defaultValue={250}>

> The delay in milliseconds that the DataGrid waits until it considers scrolling to be stopped. Also used when lazy loading is to fetch the next batch of data.
This also determines when the <PropLink name="onScrollStop" /> callback prop is called.

<Sandpack title="Scroll stop delay for lazy loading">

```ts file="scrollStopDelay-lazy-load-example.page.tsx"

```

</Sandpack>

</Prop>



<Prop name="headerOptions" type="{alwaysReserveSpaceForSortIcon: boolean}" >

> Various header configurations for the DataGrid.
Expand Down Expand Up @@ -2885,6 +2903,14 @@ It will never be called again after the component is ready.
</Prop>
<Prop name="onScrollStop" type="()=>void">
> Triggered when the user has stopped scrolling (after <PropLink name="scrollStopDelay" /> milliseconds).
This is called when the user stops scrolling for a period of time - as configured by <PropLink name="scrollStopDelay" /> (milliseconds).
</Prop>
<Prop name="onScrollToBottom" type="()=>void">
> Triggered when the user has scrolled to the bottom of the component
Expand Down
113 changes: 113 additions & 0 deletions www/content/docs/reference/scrollStopDelay-lazy-load-example.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import {
InfiniteTable,
DataSource,
DataSourceData,
InfiniteTablePropColumns,
} from '@infinite-table/infinite-react';
import * as React from 'react';
import { useMemo } from 'react';

type Developer = {
id: number;
firstName: string;
lastName: string;
country: string;
city: string;
currency: string;
preferredLanguage: string;
stack: string;
canDesign: 'yes' | 'no';
hobby: string;
salary: number;
age: number;
};

const columns: InfiniteTablePropColumns<Developer> = {
id: { field: 'id', header: 'ID', defaultWidth: 100 },
salary: { field: 'salary', header: 'Salary' },
age: { field: 'age', header: 'Age' },
firstName: { field: 'firstName', header: 'First Name' },
preferredLanguage: {
field: 'preferredLanguage',
header: 'Preferred Language',
},
lastName: { field: 'lastName', header: 'Last Name' },
country: { field: 'country', header: 'Country' },
city: { field: 'city', header: 'City' },
currency: { field: 'currency', header: 'Currency' },
stack: { field: 'stack', header: 'Stack' },
canDesign: { field: 'canDesign', header: 'Can Design' },
hobby: { field: 'hobby', header: 'Hobby' },
};

export default function App() {
const lazyLoad = useMemo(() => ({ batchSize: 40 }), []);
return (
<DataSource<Developer>
data={dataSource}
primaryKey="id"
lazyLoad={lazyLoad}
>
<InfiniteTable<Developer>
columns={columns}
columnDefaultWidth={130}
scrollStopDelay={50}
/>
</DataSource>
);
}

const dataSource: DataSourceData<Developer> = ({
pivotBy,
aggregationReducers,
groupBy,

lazyLoadStartIndex,
lazyLoadBatchSize,
groupKeys = [],
sortInfo,
}) => {
if (sortInfo && !Array.isArray(sortInfo)) {
sortInfo = [sortInfo];
}
const startLimit: string[] = [];
if (lazyLoadBatchSize && lazyLoadBatchSize > 0) {
const start = lazyLoadStartIndex || 0;
startLimit.push(`start=${start}`);
startLimit.push(`limit=${lazyLoadBatchSize}`);
}
const args = [
...startLimit,
pivotBy
? 'pivotBy=' + JSON.stringify(pivotBy.map((p) => ({ field: p.field })))
: null,
`groupKeys=${JSON.stringify(groupKeys)}`,
groupBy
? 'groupBy=' + JSON.stringify(groupBy.map((p) => ({ field: p.field })))
: null,
sortInfo
? 'sortInfo=' +
JSON.stringify(
sortInfo.map((s) => ({
field: s.field,
dir: s.dir,
})),
)
: null,
aggregationReducers
? 'reducers=' +
JSON.stringify(
Object.keys(aggregationReducers).map((key) => ({
field: aggregationReducers[key].field,
id: key,
name: aggregationReducers[key].reducer,
})),
)
: null,
]
.filter(Boolean)
.join('&');
return fetch(
process.env.NEXT_PUBLIC_BASE_URL + `/developers10k-sql?` + args,
).then((r) => r.json());
};

0 comments on commit 4ec13d7

Please sign in to comment.