@@ -4,20 +4,20 @@ The Data Grid package was developed to aid in the structuring of data. By using
4
4
5
5
To add the Data Grid package to your library run
6
6
7
- ``` sh
7
+ ``` markdown
8
8
npm install @puppet/data-grid
9
9
```
10
10
11
11
In your .js file which will be rendering the Data Grid Table component you can reference your node modules instance with the following command:
12
12
13
- ``` jsx
13
+ ``` markdown
14
14
import { Table } from '@puppet/data-grid';
15
15
```
16
16
17
17
In your app level index.scss add the command below to import the Data Grids styles
18
18
19
- ``` jsx
20
- @ import ' ~@puppet/data-grid/dist/index' ;
19
+ ``` markdown
20
+ import '~@puppet/data-grid/dist/index';
21
21
```
22
22
23
23
### Basic use
@@ -984,3 +984,246 @@ const columns = [
984
984
985
985
< Table data= {data} columns= {columns} / > ;
986
986
```
987
+
988
+ ### Selection and Pagination
989
+
990
+ Once we start adding multiple patterns together it is very easy to start confusing the end user. Thats why in the data grid when selecting and paginating together we treat each page header click as page specific and use additional badges in the header for cross pagination selecting and clearing. It's important to remember that a column header checkbox is used to show the state of the page visible. Intermediate and check all states on one page should not be shown on the next.
991
+
992
+ ``` jsx
993
+ import { Link , Heading } from ' @puppet/react-components' ;
994
+ import { TablePageSelector , TableFooter } from ' ../index' ;
995
+
996
+ const data = [
997
+ {
998
+ eventType: ' Application Control' ,
999
+ affectedDevices: 0 ,
1000
+ detections: 1000 ,
1001
+ sorted: ' asc' ,
1002
+ Link: < Link href= " https://puppet.com/" > Help to fix< / Link> ,
1003
+ unique: 6 ,
1004
+ },
1005
+ {
1006
+ eventType: ' Virus/Malware' ,
1007
+ affectedDevices: 20 ,
1008
+ detections: 634 ,
1009
+ unique: 1 ,
1010
+ Link: < Link href= " https://puppet.com/" > Help to fix< / Link> ,
1011
+ },
1012
+ {
1013
+ eventType: ' Spyware/Grayware' ,
1014
+ affectedDevices: 20 ,
1015
+ detections: 634 ,
1016
+ Link: < Link href= " https://puppet.com/" > Help to fix< / Link> ,
1017
+ unique: 2 ,
1018
+ },
1019
+ {
1020
+ eventType: ' URL Filtering' ,
1021
+ affectedDevices: 16 ,
1022
+ detections: 599 ,
1023
+ Link: < Link href= " https://puppet.com/" > Help to fix< / Link> ,
1024
+ unique: 3 ,
1025
+ },
1026
+ {
1027
+ eventType: ' Web Reputation' ,
1028
+ affectedDevices: 15 ,
1029
+ detections: 598 ,
1030
+ Link: < Link href= " https://puppet.com/" > Help to fix< / Link> ,
1031
+ unique: 4 ,
1032
+ },
1033
+ {
1034
+ eventType: ' Network Virus' ,
1035
+ affectedDevices: 15 ,
1036
+ detections: 497 ,
1037
+ Link: < Link href= " https://puppet.com/" > Help to fix< / Link> ,
1038
+ unique: 5 ,
1039
+ },
1040
+
1041
+ {
1042
+ eventType: ' Application Controls' ,
1043
+ affectedDevices: 0 ,
1044
+ detections: 0 ,
1045
+ Link: < Link href= " https://puppet.com/" > Help to fix< / Link> ,
1046
+ unique: 7 ,
1047
+ },
1048
+ ];
1049
+
1050
+ const columns = [
1051
+ {
1052
+ label: ' Event Type1' ,
1053
+ dataKey: ' eventType' ,
1054
+ },
1055
+ { label: ' Affected Devices' , dataKey: ' affectedDevices' },
1056
+
1057
+ { label: ' Detections' , dataKey: ' detections' },
1058
+ { label: ' Linked field' , dataKey: ' Link' },
1059
+ ];
1060
+
1061
+ class StatefulParent extends React .Component {
1062
+ constructor () {
1063
+ super ();
1064
+ this .state = { CurrentPage: 1 , checkAll: false , data, indeterminateState: false , showSelectAllBadge: false , Pages: {arrayOfArrays: []}, nodesPerPage: 5 };
1065
+ this .pageSelectFunc = this .pageSelectFunc .bind (this );
1066
+ this .breakIntoMultiplePages = this .breakIntoMultiplePages .bind (this );
1067
+ this .onRowSelected = this .onRowSelected .bind (this );
1068
+ this .onHeaderSelected = this .onHeaderSelected .bind (this );
1069
+ this .onSelectAllBadgeClick = this .onSelectAllBadgeClick .bind (this );
1070
+ this .onClearAllBadgeClick = this .onClearAllBadgeClick .bind (this );
1071
+ }
1072
+
1073
+ componentWillMount () {
1074
+ const dataToPages = this .breakIntoMultiplePages (data, 5 )
1075
+ this .setState ({Pages: dataToPages})
1076
+ }
1077
+
1078
+ pageSelectFunc (newPage ) {
1079
+ const { CurrentPage , Pages } = this .state ;
1080
+ this .checkIfIndeterminateState (Pages)
1081
+ this .setState ({ CurrentPage: newPage });
1082
+ }
1083
+
1084
+ breakIntoMultiplePages (originalArray , pageSize ) {
1085
+ const arrayOfArrays = [];
1086
+ for (let i = 0 ; i < originalArray .length ; i += pageSize) {
1087
+ arrayOfArrays .push (originalArray .slice (i, i + pageSize));
1088
+ }
1089
+ return { arrayOfArrays };
1090
+ }
1091
+
1092
+ checkIfIndeterminateState (Pages ) {
1093
+ const { data , indeterminateState , checkAll , CurrentPage } = this .state ;
1094
+
1095
+ let selectedOnCurrentPage = Pages .arrayOfArrays [CurrentPage - 1 ].filter (e => e .selected === true );
1096
+ let currentPageLength = Pages .arrayOfArrays [CurrentPage - 1 ].length
1097
+
1098
+ if (selectedOnCurrentPage .length > 0 && indeterminateState === false && checkAll === false ) {
1099
+ this .setState ({ indeterminateState: true });
1100
+ } else if (
1101
+ (selectedOnCurrentPage .length === 0 && indeterminateState === true ) ||
1102
+ (selectedOnCurrentPage .length === 0 && checkAll === true )
1103
+ ) {
1104
+ this .setState ({ indeterminateState: false , checkAll: false });
1105
+ }
1106
+ if (selectedOnCurrentPage .length === currentPageLength && checkAll === false ) {
1107
+ this .setState ({ indeterminateState: false , checkAll: true });
1108
+ }
1109
+ }
1110
+
1111
+ onHeaderSelected (checked ) {
1112
+ const { data: stateData , indeterminateState , show , showSelectAllBadge , CurrentPage , Pages } = this .state ;
1113
+
1114
+ this .setState ({ indeterminateState: false , checkAll: checked });
1115
+
1116
+ const x = Pages .arrayOfArrays [CurrentPage - 1 ]
1117
+ let newObj = stateData;
1118
+
1119
+ x .forEach ((row ) => {
1120
+ const y = stateData .findIndex ((stateRow ) => stateRow .unique === row .unique )
1121
+ const updatedObj = { ... stateData[y], selected: checked };
1122
+ newObj .splice (y,1 , updatedObj);
1123
+ })
1124
+
1125
+ this .setState ({data: newObj})
1126
+
1127
+ }
1128
+
1129
+
1130
+ onRowSelected (checked , row ) {
1131
+ const { data: stateData , checkAll , Pages } = this .state ;
1132
+
1133
+ if (checkAll) {
1134
+ this .setState ({ checkAll: false });
1135
+ }
1136
+ // find the index of object from array that you want to update
1137
+ const objIndex = stateData .findIndex (obj => obj .unique === row .unique );
1138
+ // make new object of updated object.
1139
+ const updatedObj = { ... stateData[objIndex], selected: checked };
1140
+ // make final new array of objects by combining updated object.
1141
+ const updatedData = [
1142
+ ... stateData .slice (0 , objIndex),
1143
+ updatedObj,
1144
+ ... stateData .slice (objIndex + 1 ),
1145
+ ];
1146
+
1147
+ this .checkIfIndeterminateState (Pages)
1148
+
1149
+ this .setState ({ data: updatedData });
1150
+ }
1151
+
1152
+ onSelectAllBadgeClick (){
1153
+ const { data } = this .state ;
1154
+ const x = data
1155
+ for (let i = 0 ; i < x .length ; i += 1 ) {
1156
+ x[i].selected = true ;
1157
+ }
1158
+ this .setState ({data: x})
1159
+ }
1160
+
1161
+ onClearAllBadgeClick (){
1162
+ const { data } = this .state ;
1163
+ const x = data
1164
+ for (let i = 0 ; i < x .length ; i += 1 ) {
1165
+ x[i].selected = false ;
1166
+ }
1167
+ this .setState ({data: x})
1168
+ }
1169
+
1170
+ render () {
1171
+ const {
1172
+ CurrentPage,
1173
+ data: stateData,
1174
+ indeterminateState,
1175
+ checkAll: headerCheckboxState,
1176
+ nodesPerPage
1177
+ } = this .state ;
1178
+
1179
+ const Pages = this .breakIntoMultiplePages (stateData, 5 )
1180
+ const PageLength = Pages .arrayOfArrays [CurrentPage - 1 ].length
1181
+ const PageCount = Pages .arrayOfArrays .length ;
1182
+ const renderPages = CurrentPage - 1 ;
1183
+ const currentNode = ` ${ nodesPerPage * CurrentPage} ` ;
1184
+ const tableFooterText = ` ${ currentNode -
1185
+ PageLength +
1186
+ 1 } - ${ currentNode} of ${ stateData .length } nodes` ;
1187
+ const selectAllBadgeText = ` Select all ${ stateData .length } nodes`
1188
+
1189
+ this .checkIfIndeterminateState (Pages);
1190
+ const selectedCount = stateData .filter (obj => obj .selected === true ).length
1191
+
1192
+ let rowCountText = ` ${ stateData .length } nodes`
1193
+ if ( selectedCount > 0 ){
1194
+ rowCountText = ` ${ selectedCount} of ${ stateData .length } nodes selected`
1195
+ }
1196
+
1197
+ return (
1198
+ < div>
1199
+ < Table .TableHeader
1200
+ showSelectAllBadge= {selectedCount > 0 && selectedCount !== stateData .length }
1201
+ rowCountText= {rowCountText}
1202
+ onSelectAllBadgeClick= {this .onSelectAllBadgeClick }
1203
+ showClearAllBadge= {selectedCount === stateData .length }
1204
+ onClearAllBadgeClick= {this .onClearAllBadgeClick }
1205
+ selectAllBadgeText= {selectAllBadgeText}/ >
1206
+ < Table
1207
+ data= {Pages .arrayOfArrays [renderPages]}
1208
+ columns= {columns}
1209
+ selectable
1210
+ onRowChecked= {this .onRowSelected }
1211
+ headerIndeterminateState= {indeterminateState}
1212
+ checkIfIndeterminateState= {this .checkIfIndeterminateState }
1213
+ headerCheckState= {headerCheckboxState}
1214
+ onHeaderChecked= {this .onHeaderSelected }
1215
+ / >
1216
+ < TableFooter>
1217
+ < TablePageSelector
1218
+ paginationCountText= {tableFooterText}
1219
+ currentPage= {CurrentPage}
1220
+ pageCount= {PageCount}
1221
+ updatePage= { this .pageSelectFunc }
1222
+ / >
1223
+ < / TableFooter>
1224
+ < / div>
1225
+ );
1226
+ }
1227
+ }
1228
+ < StatefulParent/ > ;
1229
+ ```
0 commit comments