Skip to content

ListView: add new prop - flattenItems #1973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 88 additions & 7 deletions docs/documentation/docs/controls/ListView.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ This control renders a list view for the given set of items.
- Check that you installed the `@pnp/spfx-controls-react` dependency. Check out the [getting started](../../#getting-started) page for more information about installing the dependency.
- Import the following modules to your component:

```TypeScript
```typeScript
import { ListView, IViewField, SelectionMode, GroupOrder, IGrouping } from "@pnp/spfx-controls-react/lib/ListView";
```

- Use the `ListView` control in your code as follows:

```TypeScript
```typeScript
<ListView
items={items}
viewFields={viewFields}
Expand Down Expand Up @@ -56,7 +56,7 @@ private _getSelection(items: any[]) {

**Important**: the same order of the fields defines how grouping will be applied. In the snippet the `ListView` control will first group by the `Extension` and after that by the `Author` field.

```TypeScript
```typeScript
const groupByFields: IGrouping[] = [
{
name: "Extension",
Expand All @@ -81,6 +81,86 @@ private _getDropFiles = (files) => {
}
```

## Disabling flatten items

By default, the ListView control is flattening the items passed as prop, which means that nested objects such as arrays are transformed and put at level 0. This can be a problem when manipulating items with objects or sub-arrays. When setting the prop `flattenItems` to `false`, items are returned "as provided" which enables custom rendering. See the following example:

```typescript
// ...
public render(): React.ReactElement<{}> {
const itms = [
{
id: 1,
displayName: 'Adele Vance',
email: '[email protected]',
managers: [{displayName: "Tony Stark"}, {displayName: "Natasha Romanoff"}]
},
{
id: 2,
displayName: 'Alex Wilber',
email: '[email protected]',
managers: [{displayName: "Maria Hill"}, {displayName: "Bruce Banner"}]
},
{
id: 3,
displayName: 'Megan Bowen',
email: '[email protected]',
managers: [{displayName: "Thor"}, {displayName: "Tony Stark"}]
},
];

const vwFields: IViewField[] = [
{
name: "id",
displayName: "ID",
sorting: false,
minWidth: 50,
maxWidth: 50
},
{
name: "displayName",
displayName: "Name",
sorting: true,
minWidth: 100,
maxWidth: 100
},
{
name: "email",
displayName: "E-mail",
sorting: true,
minWidth: 150,
maxWidth: 150
},
{
name: "managers",
displayName: "Managers",
sorting: true,
render: (item?: any, index?: number, column?: any): JSX.Element => {
return (
<div style={{display: 'flex', columnGap: '10px'}}>
{item.managers.map(itm => {return <span>{itm.displayName}</span>})}
</div>
);
},
minWidth: 100,
maxWidth: 100
}
];

return (
<ListView items={itms}
viewFields={vwFields}
compact={true}
selectionMode={SelectionMode.single}
showFilter={true}
dragDropFiles={true}
stickyHeader={true}
flattenItems={false}
/>
);
}
```

## Implementation

The ListView control can be configured with the following properties:
Expand All @@ -100,11 +180,12 @@ The ListView control can be configured with the following properties:
| defaultFilter | string | no | Specify the initial filter to be applied to the list. |
| dragDropFiles | boolean | no | Specify the drag and drop files area option. Default false. |
| onDrop | file | no | Event handler returns files from drag and drop. |
| stickyHeader | boolean | no | Specifies if the header of the `ListView`, including search box, is sticky |
| stickyHeader | boolean | no | Specifies if the header of the `ListView`, including search box, is sticky. |
| onRenderRow | (props: IDetailsRowProps) => JSX.Element \| null | no | Callback to override the default row rendering. |
| sortItems | (items: any[], columnName: string, descending: boolean) =&gt; any[] | no | Custom sorting function to handle sorting by column |
| className | string | no | Class name to apply additional styles on list view wrapper |
| listClassName | string | no | Class name to apply additional styles on list view |
| sortItems | (items: any[], columnName: string, descending: boolean) =&gt; any[] | no | Custom sorting function to handle sorting by column. |
| className | string | no | Class name to apply additional styles on list view wrapper. |
| listClassName | string | no | Class name to apply additional styles on list view. |
| flattenItems | boolean | no | Specify if items should be flatten or not. Default value is `true`. |

The `IViewField` has the following implementation:

Expand Down
11 changes: 9 additions & 2 deletions src/controls/listView/IListView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ export interface IListViewProps {
* @returns sorted collection of items
*/
sortItems?: (items: any[], columnName: string, descending: boolean) => any[]; // eslint-disable-line @typescript-eslint/no-explicit-any
/**
* Specify if items should be flatten or not.
* Default value is `true`.
*/
flattenItems?: boolean;
}

export interface IListViewState {
Expand All @@ -96,11 +101,13 @@ export interface IListViewState {
*/
items?: any[]; // eslint-disable-line @typescript-eslint/no-explicit-any
/**
* Given column defitions.
* Given column definitions.
* If none are provided, default columns will be created based on the item's properties.
*/
columns?: IColumn[];

/**
* Grouping applied to the view.
*/
groups?: IGroup[];

}
Expand Down
2 changes: 1 addition & 1 deletion src/controls/listView/ListView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ export class ListView extends React.Component<IListViewProps, IListViewState> {
let columns: IColumn[] = null;
// Check if a set of items was provided
if (typeof items !== 'undefined' && items !== null) {
tempState.items = this._flattenItems(items);
tempState.items = props.flattenItems === undefined || props.flattenItems ? this._flattenItems(items) : items;
}

// Check if an icon needs to be shown
Expand Down