1
1
import * as React from 'react' ;
2
- import { DetailsList , DetailsListLayoutMode , Selection , SelectionMode } from 'office-ui-fabric-react/lib/DetailsList' ;
2
+ import { DetailsList , DetailsListLayoutMode , Selection , SelectionMode , IGroup } from 'office-ui-fabric-react/lib/DetailsList' ;
3
3
import { IListViewProps , IListViewState , IViewField } from './IListView' ;
4
4
import { IColumn } from 'office-ui-fabric-react/lib/components/DetailsList' ;
5
5
import { findIndex , has , sortBy , isEqual , cloneDeep } from '@microsoft/sp-lodash-subset' ;
6
6
import { FileTypeIcon , IconType } from '../fileTypeIcon/index' ;
7
+ import * as strings from 'ControlStrings' ;
7
8
8
9
/**
9
10
* File type icon component
@@ -49,6 +50,74 @@ export class ListView extends React.Component<IListViewProps, IListViewState> {
49
50
}
50
51
}
51
52
53
+ /**
54
+ * Specify result grouping for the list rendering
55
+ * @param items
56
+ * @param groupByFields
57
+ */
58
+ private _getGroups ( items : any [ ] , groupByFields : string [ ] , level : number = 0 , startIndex : number = 0 ) : { items : any [ ] , groups : IGroup [ ] } {
59
+ // Group array which stores the configured grouping
60
+ let groups : IGroup [ ] = [ ] ;
61
+ let updatedItemsOrder : any [ ] = [ ] ;
62
+ // Check if there are groupby fields set
63
+ if ( groupByFields ) {
64
+ const groupField = groupByFields [ level ] ;
65
+ // Check if grouping is configured
66
+ if ( groupByFields && groupByFields . length > 0 ) {
67
+ // Create grouped items object
68
+ const groupedItems = { } ;
69
+ items . forEach ( ( item : any ) => {
70
+ let groupName = item [ groupField ] ;
71
+ // Check if the group name exists
72
+ if ( typeof groupName === "undefined" ) {
73
+ // Set the default empty label for the field
74
+ groupName = strings . ListViewGroupEmptyLabel ;
75
+ }
76
+ // Check if group name is a number, this can cause sorting issues
77
+ if ( typeof groupName === "number" ) {
78
+ groupName = `${ groupName } .` ;
79
+ }
80
+
81
+ // Check if current group already exists
82
+ if ( typeof groupedItems [ groupName ] === "undefined" ) {
83
+ // Create a new group of items
84
+ groupedItems [ groupName ] = [ ] ;
85
+ }
86
+ groupedItems [ groupName ] . push ( item ) ;
87
+ } ) ;
88
+
89
+ // Loop over all the groups
90
+ for ( const groupItems in groupedItems ) {
91
+ // Add the items to the updated items order array
92
+ groupedItems [ groupItems ] . forEach ( ( item ) => {
93
+ updatedItemsOrder . push ( item ) ;
94
+ } ) ;
95
+ // Retrieve the total number of items per group
96
+ const totalItems = groupedItems [ groupItems ] . length ;
97
+ // Create the new group
98
+ const group : IGroup = {
99
+ name : groupItems === "undefined" ? strings . ListViewGroupEmptyLabel : groupItems ,
100
+ key : groupItems === "undefined" ? strings . ListViewGroupEmptyLabel : groupItems ,
101
+ startIndex : startIndex ,
102
+ count : totalItems ,
103
+ } ;
104
+ // Check if child grouping available
105
+ if ( groupByFields [ level + 1 ] ) {
106
+ // Get the child groups
107
+ group . children = this . _getGroups ( groupedItems [ groupItems ] , groupByFields , ( level + 1 ) , startIndex ) . groups ;
108
+ }
109
+ // Increase the start index for the next group
110
+ startIndex = startIndex + totalItems ;
111
+ groups . push ( group ) ;
112
+ }
113
+ }
114
+ }
115
+ return {
116
+ items : updatedItemsOrder ,
117
+ groups
118
+ } ;
119
+ }
120
+
52
121
/**
53
122
* Process all the component properties
54
123
*/
@@ -75,6 +144,17 @@ export class ListView extends React.Component<IListViewProps, IListViewState> {
75
144
76
145
// Add the columns to the temporary state
77
146
tempState . columns = columns ;
147
+
148
+ // Add grouping to the list view
149
+ const grouping = this . _getGroups ( tempState . items , this . props . groupByFields ) ;
150
+ if ( grouping . groups . length > 0 ) {
151
+ tempState . groups = grouping . groups ;
152
+ // Update the items
153
+ tempState . items = grouping . items ;
154
+ } else {
155
+ tempState . groups = null ;
156
+ }
157
+
78
158
// Update the current component state with the new values
79
159
this . setState ( tempState ) ;
80
160
}
@@ -203,10 +283,13 @@ export class ListView extends React.Component<IListViewProps, IListViewState> {
203
283
}
204
284
return c ;
205
285
} ) ;
286
+ // Update the grouping
287
+ const groupedItems = this . _getGroups ( sortedItems , this . props . groupByFields ) ;
206
288
// Update the items and columns
207
289
this . setState ( {
208
- items : sortedItems ,
209
- columns : sortedColumns
290
+ items : groupedItems . groups . length > 0 ? groupedItems . items : sortedItems ,
291
+ columns : sortedColumns ,
292
+ groups : groupedItems . groups . length > 0 ? groupedItems . groups : null ,
210
293
} ) ;
211
294
}
212
295
}
@@ -228,11 +311,13 @@ export class ListView extends React.Component<IListViewProps, IListViewState> {
228
311
* Default React component render method
229
312
*/
230
313
public render ( ) : React . ReactElement < IListViewProps > {
314
+
231
315
return (
232
316
< div >
233
317
< DetailsList
234
318
items = { this . state . items }
235
319
columns = { this . state . columns }
320
+ groups = { this . state . groups }
236
321
selectionMode = { this . props . selectionMode || SelectionMode . none }
237
322
selection = { this . _selection }
238
323
layoutMode = { DetailsListLayoutMode . justified }
0 commit comments