Skip to content

Commit 02ca876

Browse files
committed
(CISC-1585) Select all with pagination, new icons, check all empty state bug fix, table actions
1 parent 3a731b8 commit 02ca876

File tree

8 files changed

+416
-31
lines changed

8 files changed

+416
-31
lines changed

packages/data-grid/src/__test__/__snapshots__/Table.test.jsx.snap

+4-4
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ exports[`Snapshot test Check component matches previous HTML snapshot 1`] = `
7878
fixed={false}
7979
fixedColumn={false}
8080
headerCheckState={false}
81-
headerIndeterminateState={true}
81+
headerIndeterminateState={false}
8282
horizontalScroll={false}
8383
loading={false}
8484
loadingMessage="Loading"
@@ -126,7 +126,7 @@ exports[`Snapshot test Check component matches previous HTML snapshot 1`] = `
126126
},
127127
]
128128
}
129-
headerIndeterminateState={true}
129+
headerIndeterminateState={false}
130130
loading={false}
131131
loadingMessage="Loading"
132132
onSelectAll={[Function]}
@@ -443,7 +443,7 @@ exports[`Snapshot test Check component matches previous HTML snapshot 2`] = `
443443
fixed={false}
444444
fixedColumn={false}
445445
headerCheckState={false}
446-
headerIndeterminateState={true}
446+
headerIndeterminateState={false}
447447
horizontalScroll={false}
448448
loading={false}
449449
loadingMessage="Loading"
@@ -491,7 +491,7 @@ exports[`Snapshot test Check component matches previous HTML snapshot 2`] = `
491491
},
492492
]
493493
}
494-
headerIndeterminateState={true}
494+
headerIndeterminateState={false}
495495
loading={false}
496496
loadingMessage="Loading"
497497
onSelectAll={[Function]}

packages/data-grid/src/__test__/__snapshots__/quickFitler.test.jsx.snap

-6
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ exports[`Snapshot test Check component matches previous HTML snapshot 1`] = `
253253
onMouseEnter={[Function]}
254254
selected={false}
255255
svg={null}
256-
type="option"
257256
>
258257
<li
259258
aria-selected={false}
@@ -306,7 +305,6 @@ exports[`Snapshot test Check component matches previous HTML snapshot 1`] = `
306305
onMouseEnter={[Function]}
307306
selected={false}
308307
svg={null}
309-
type="option"
310308
>
311309
<li
312310
aria-selected={false}
@@ -359,7 +357,6 @@ exports[`Snapshot test Check component matches previous HTML snapshot 1`] = `
359357
onMouseEnter={[Function]}
360358
selected={false}
361359
svg={null}
362-
type="option"
363360
>
364361
<li
365362
aria-selected={false}
@@ -605,7 +602,6 @@ exports[`Snapshot test Check component matches previous HTML snapshot 1`] = `
605602
onMouseEnter={[Function]}
606603
selected={false}
607604
svg={null}
608-
type="option"
609605
>
610606
<li
611607
aria-selected={false}
@@ -658,7 +654,6 @@ exports[`Snapshot test Check component matches previous HTML snapshot 1`] = `
658654
onMouseEnter={[Function]}
659655
selected={false}
660656
svg={null}
661-
type="option"
662657
>
663658
<li
664659
aria-selected={false}
@@ -711,7 +706,6 @@ exports[`Snapshot test Check component matches previous HTML snapshot 1`] = `
711706
onMouseEnter={[Function]}
712707
selected={false}
713708
svg={null}
714-
type="option"
715709
>
716710
<li
717711
aria-selected={false}

packages/data-grid/src/table/README.md

+247-4
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@ The Data Grid package was developed to aid in the structuring of data. By using
44

55
To add the Data Grid package to your library run
66

7-
```sh
7+
```markdown
88
npm install @puppet/data-grid
99
```
1010

1111
In your .js file which will be rendering the Data Grid Table component you can reference your node modules instance with the following command:
1212

13-
```jsx
13+
```markdown
1414
import { Table } from '@puppet/data-grid';
1515
```
1616

1717
In your app level index.scss add the command below to import the Data Grids styles
1818

19-
```jsx
20-
@import '~@puppet/data-grid/dist/index';
19+
```markdown
20+
import '~@puppet/data-grid/dist/index';
2121
```
2222

2323
### Basic use
@@ -984,3 +984,246 @@ const columns = [
984984

985985
<Table data={data} columns={columns} />;
986986
```
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+
```

packages/data-grid/src/table/Table.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ const defaultProps = {
106106
onHeaderChecked: () => {},
107107
onRowClick: () => {},
108108
headerCheckState: false,
109-
headerIndeterminateState: true,
109+
headerIndeterminateState: false,
110110
};
111111

112112
const defaultColumnDefs = {

0 commit comments

Comments
 (0)