Master Detail in AdapTable
You can leverage the master detail functionality of Infinite Table in AdapTable to show a detail grid for each row in the main grid.
To implement master detail, you need to intercept the InfiniteTable
component and hook the detail rendering into that.
import { Adaptable, AdaptableProps } from '@adaptabletools/adaptable'
const CustomComponents: AdaptableProps<DATA_TYPE>['components'] = {
InfiniteTable: (props) => {
// you can add your custom logic here
return <InfiniteTable {...props} />
}
}
<Adaptable.Provider
data={[...]} // DATA_TYPE[]
primaryKey="id"
adaptableId={`custom-infinite-component`}
defaultState={state}
components={CustomComponents}
>
<Adaptable.UI />
</Adaptable.Provider>
Note
Prior to version 0.5.0
, the components
prop had to be passed to the <Adaptable.UI />
component. Starting with version 0.5.0
, the components
prop should be passed to the <Adaptable.Provider />
component.
Take a look at the example below to see a fully working master detail grid. The master grid is your Adaptable DataGrid configuration, while the detail grid is configured to render a custom InfiniteTable
component.
The main Adaptable DataGrid shows a list of license types. Expand each license type to see a detail grid with web frameworks that use that license type.
Note
In future releases, we will provide a more streamlined way to work with master detail grids. In the current version, you have to intercept the InfiniteTable
rendering and do the wiring yourself, as demonstrated in the example above.
Intercepting the InfiniteTable rendering
As detailed above, for setting up master-detail, the first step is to intercept the rendering of the InfiniteTable
component and define the rowDetailRenderer
const components: AdaptableProps<License>['components'] = {
InfiniteTable: (props: InfiniteTableProps<License>) => {
const columns = props.columns;
// make the first column render the row detail icon
columns[Object.keys(columns)[0]].renderRowDetailIcon = true
return (
<InfiniteTable<License>
{...props}
columns={columns}
{/* define the rowDetailRenderer */}
rowDetailRenderer={rowDetailRenderer}
/>
);
},
};
export default function App() {
return (
<>
<Adaptable.Provider
data={licenses}
primaryKey="id"
adaptableId={`custom-infinite-component`}
licenseKey={process.env.NEXT_PUBLIC_ADAPTABLE_LICENSE_KEY}
defaultState={state}
components={components}
>
<Adaptable.UI />
</Adaptable.Provider>
</>
);
}
Note
Make sure you don't forget to make one of the columns render the row detail icon. This is done by setting the renderRowDetailIcon
property to true
on the column definition - see detailed steps in the Infinite Table master-detail documentation page.
After you define the custom InfiniteTable
component rendering, make sure you define the rowDetailRenderer
function. This function will be called for each row in the main grid and should return the detail grid for that row.
function rowDetailRenderer(rowInfo: InfiniteTableRowInfo<License>) {
// you can
return (
<div
style={{
display: 'flex',
flex: 1,
flexFlow: 'column',
height: '100%',
}}
>
<h3>Web frameworks ({rowInfo.data!.type})</h3>
<DataSource<WebFramework> data={detailDetaSource} primaryKey={'id'}>
<InfiniteTable<WebFramework> columns={detailColumns} />
</DataSource>
</div>
Note
The data
prop of the detail <DataSource />
is a function that can return a promise, and it has access to the masterRowInfo
object, which contains the information about the master row.
You can read more about loading the detail DataSource in the Infinite Table documentation.