Skip to content

Commit fae0642

Browse files
Merge branch 'feat/listview-flatten' of https://github.com/pnp/sp-dev-fx-controls-react into dev
2 parents 78b64f5 + 86c2d38 commit fae0642

File tree

3 files changed

+98
-10
lines changed

3 files changed

+98
-10
lines changed

docs/documentation/docs/controls/ListView.md

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ This control renders a list view for the given set of items.
1717
- 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.
1818
- Import the following modules to your component:
1919

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

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

26-
```TypeScript
26+
```typeScript
2727
<ListView
2828
items={items}
2929
viewFields={viewFields}
@@ -56,7 +56,7 @@ private _getSelection(items: any[]) {
5656

5757
**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.
5858

59-
```TypeScript
59+
```typeScript
6060
const groupByFields: IGrouping[] = [
6161
{
6262
name: "Extension",
@@ -81,6 +81,86 @@ private _getDropFiles = (files) => {
8181
}
8282
```
8383

84+
## Disabling flatten items
85+
86+
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:
87+
88+
```typescript
89+
// ...
90+
public render(): React.ReactElement<{}> {
91+
const itms = [
92+
{
93+
id: 1,
94+
displayName: 'Adele Vance',
95+
email: 'adelev@contoso.onmicrosoft.com',
96+
managers: [{displayName: "Tony Stark"}, {displayName: "Natasha Romanoff"}]
97+
},
98+
{
99+
id: 2,
100+
displayName: 'Alex Wilber',
101+
email: 'alexw@contoso.onmicrosoft.com',
102+
managers: [{displayName: "Maria Hill"}, {displayName: "Bruce Banner"}]
103+
},
104+
{
105+
id: 3,
106+
displayName: 'Megan Bowen',
107+
email: 'meganb@contoso.onmicrosoft.com',
108+
managers: [{displayName: "Thor"}, {displayName: "Tony Stark"}]
109+
},
110+
];
111+
112+
const vwFields: IViewField[] = [
113+
{
114+
name: "id",
115+
displayName: "ID",
116+
sorting: false,
117+
minWidth: 50,
118+
maxWidth: 50
119+
},
120+
{
121+
name: "displayName",
122+
displayName: "Name",
123+
sorting: true,
124+
minWidth: 100,
125+
maxWidth: 100
126+
},
127+
{
128+
name: "email",
129+
displayName: "E-mail",
130+
sorting: true,
131+
minWidth: 150,
132+
maxWidth: 150
133+
},
134+
{
135+
name: "managers",
136+
displayName: "Managers",
137+
sorting: true,
138+
render: (item?: any, index?: number, column?: any): JSX.Element => {
139+
return (
140+
<div style={{display: 'flex', columnGap: '10px'}}>
141+
{item.managers.map(itm => {return <span>{itm.displayName}</span>})}
142+
</div>
143+
);
144+
},
145+
minWidth: 100,
146+
maxWidth: 100
147+
}
148+
];
149+
150+
return (
151+
<ListView items={itms}
152+
viewFields={vwFields}
153+
compact={true}
154+
selectionMode={SelectionMode.single}
155+
showFilter={true}
156+
dragDropFiles={true}
157+
stickyHeader={true}
158+
flattenItems={false}
159+
/>
160+
);
161+
}
162+
```
163+
84164
## Implementation
85165

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

109190
The `IViewField` has the following implementation:
110191

src/controls/listView/IListView.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ export interface IListViewProps {
8484
* @returns sorted collection of items
8585
*/
8686
sortItems?: (items: any[], columnName: string, descending: boolean) => any[]; // eslint-disable-line @typescript-eslint/no-explicit-any
87+
/**
88+
* Specify if items should be flatten or not.
89+
* Default value is `true`.
90+
*/
91+
flattenItems?: boolean;
8792
}
8893

8994
export interface IListViewState {
@@ -96,11 +101,13 @@ export interface IListViewState {
96101
*/
97102
items?: any[]; // eslint-disable-line @typescript-eslint/no-explicit-any
98103
/**
99-
* Given column defitions.
104+
* Given column definitions.
100105
* If none are provided, default columns will be created based on the item's properties.
101106
*/
102107
columns?: IColumn[];
103-
108+
/**
109+
* Grouping applied to the view.
110+
*/
104111
groups?: IGroup[];
105112

106113
}

src/controls/listView/ListView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ export class ListView extends React.Component<IListViewProps, IListViewState> {
236236
let columns: IColumn[] = null;
237237
// Check if a set of items was provided
238238
if (typeof items !== 'undefined' && items !== null) {
239-
tempState.items = this._flattenItems(items);
239+
tempState.items = props.flattenItems === undefined || props.flattenItems ? this._flattenItems(items) : items;
240240
}
241241

242242
// Check if an icon needs to be shown

0 commit comments

Comments
 (0)