Skip to content

Commit 7548269

Browse files
committed
infinite scroll WIP added data change WIP expandable tree item
1 parent 5287289 commit 7548269

8 files changed

Lines changed: 307 additions & 59 deletions

File tree

docs/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
- __Fixed__ for any bug fixes.
1212
- __Security__ in case of vulnerabilities.
1313

14+
## [0.1.0] - 16-06-2019
15+
###Removed
16+
- infinite scroll
17+
18+
### Added
19+
- WIP added data change
20+
- WIP expandable tree item
21+
1422
## [0.1.0] - 03-06-2019
1523
###Changed
1624
- naming of functions in pagination logic

src/App.test.js

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,70 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
3+
import { configure, mount, shallow, render } from "enzyme";
4+
import Adapter from "enzyme-adapter-react-16";
5+
6+
//Components
37
import App from './App';
48

5-
it('renders without crashing', () => {
6-
const div = document.createElement('div');
7-
ReactDOM.render(<App />, div);
8-
ReactDOM.unmountComponentAtNode(div);
9+
configure({ adapter: new Adapter() });
10+
11+
describe("App Component", () => {
12+
it("renders without crashing in 'debug' mode " + new Date(), () => {
13+
const component = shallow(<App debug />);
14+
expect(component).toMatchSnapshot();
15+
component.unmount();
16+
});
17+
});
18+
19+
/***
20+
//the below mount test is for components that may interact with DOM API, or use React lifecycle methods in order to fully test the component.
21+
describe('App Component', () => {
22+
it("renders without crashing in 'debug' mode", () => {
23+
24+
const component = mount(<App debug />);
25+
expect(component).toMatchSnapshot();
26+
component.unmount();
27+
});
28+
});
29+
30+
// test interacting with a child component.
31+
it('should be possible to activate button with Spacebar', () => {
32+
const component = mount(<A-Component-Here />);
33+
component
34+
.find('button#my-button-one')
35+
.simulate('keydown', { keyCode: 32 });
36+
expect(component).toMatchSnapshot();
37+
component.unmount();
38+
});
39+
***/
40+
41+
/***
42+
// the below 2 shallow test are for simple non-interactive components.
43+
describe('App Component', () => {
44+
it('should render correctly with no props', () => {
45+
const component = shallow(<App/>);
46+
47+
expect(component).toMatchSnapshot();
48+
});
49+
});
50+
51+
describe('A-Component-Here', () => {
52+
it('should render banner text correctly with given strings', () => {
53+
const strings = ['one', 'two'];
54+
const component = shallow(<A-Component-Here list={strings} />);
55+
expect(component).toMatchSnapshot();
56+
});
57+
});
58+
59+
// Check that a function passed as props is successfully called.
60+
const clickFn = jest.fn();
61+
describe('A-Component-Here', () => {
62+
it('button click should hide component', () => {
63+
const component = shallow(<A-Component-Here onClick={clickFn} />);
64+
component
65+
.find('button#my-button-two')
66+
.simulate('click');
67+
expect(clickFn).toHaveBeenCalled();
68+
});
969
});
70+
***/

src/Components/data-table.js

Lines changed: 116 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,113 @@ import React, { PureComponent } from "react";
22

33
//Components
44
import Preloader from "./pre-loader";
5+
import ScrollButton from "./scroll-to-top";
56
import TableHeaders from "./table-headers";
67
import TableRows from "./table-rows";
78
import Pagination from "./pagination";
89

910
class RecordTable extends PureComponent {
1011
state = {
12+
error: false,
13+
isLoading: false,
1114
columns: [
1215
{
16+
Header: "",
17+
commentHeader: "",
18+
Value: "",
19+
commentValue: "",
20+
sortOn: "",
21+
childItem: null,
22+
}, {
1323
Header: "Id",
24+
commentHeader: "Id",
1425
Value: "id",
26+
commentValue: "id",
1527
sortOn: "id",
28+
childItem: null,
1629
}, {
17-
Header: "Content",
18-
Value: "body",
19-
sortOn: "body",
30+
Header: "Name",
31+
commentHeader: "Name",
32+
Value: "name",
33+
commentValue: "name",
34+
sortOn: "name",
35+
childItem: null,
36+
}, {
37+
Header: "username",
38+
commentHeader: "",
39+
Value: "username",
40+
commentValue: "",
41+
sortOn: "username",
42+
childItem: null,
2043
}, {
2144
Header: "Email",
45+
commentHeader: "Email",
2246
Value: "email",
47+
commentValue: "email",
2348
sortOn: "email",
49+
childItem: null,
2450
}, {
25-
Header: "Name",
26-
Value: "name",
27-
sortOn: "name",
28-
},
51+
Header: "Phone",
52+
commentHeader: "",
53+
Value: "phone",
54+
commentValue: "",
55+
sortOn: "phone",
56+
childItem: null,
57+
}, {
58+
Header: "Website",
59+
commentHeader: "",
60+
Value: "website",
61+
commentValue: "",
62+
sortOn: "website",
63+
childItem: null,
64+
}, {
65+
Header: "Address",
66+
commentHeader: "",
67+
Value: "address.city",
68+
commentValue: "",
69+
sortOn: "adress.city",
70+
childItem: [
71+
{
72+
Value: "address.zipcode",
73+
}, {
74+
Value: "address.street",
75+
}
76+
],
77+
}, {
78+
Header: "",
79+
commentHeader: "Comment",
80+
Value: "",
81+
commentValue: "body",
82+
sortOn: "body",
83+
childItem: null,
84+
},
2985
],
3086
data: [],
31-
32-
isLoading: true,
33-
error: false,
87+
checked: false,
3488

3589
sortOrder: {
3690
key: "asc",
3791
},
3892
currentPage: 1,
39-
recordsPerPage: 30,
93+
recordsPerPage: 15,
4094

4195
query: "",
4296
PlaceHolder: "Table filter",
4397
};
44-
componentDidMount() {
45-
this.loadRecordsFromServer();
98+
99+
componentWillMount() {
100+
this.loadDataFromServer();
46101
}
47102
// Initial call to the server for records
48-
loadRecordsFromServer() {
103+
loadDataFromServer = () => {
104+
const { checked } = this.state;
105+
49106
const xmlhr = new XMLHttpRequest();
50-
const url = "https://jsonplaceholder.typicode.com/comments";
107+
const url = !checked ? `https://jsonplaceholder.typicode.com/comments` :
108+
`https://jsonplaceholder.typicode.com/users`
109+
;
110+
this.setState({ isLoading: true });
111+
51112
xmlhr.open("GET", url, true);
52113
xmlhr.onload = () => {
53114
if (xmlhr.readyState === xmlhr.DONE) {
@@ -60,13 +121,13 @@ class RecordTable extends PureComponent {
60121
} else {
61122
this.setState({
62123
error: true,
124+
isLoading: false,
63125
});
64126
}
65127
}
66128
};
67129
xmlhr.send();
68130
}
69-
70131
// Column Sort handler + Logic
71132
columnSort = (key) => {
72133
const { data, sortOrder } = this.state;
@@ -134,9 +195,18 @@ class RecordTable extends PureComponent {
134195
currentPage: Math.ceil(data.length / recordsPerPage),
135196
});
136197
}
198+
handleCheckBox = () => {
199+
const { checked } = this.state;
200+
this.setState({
201+
recordsPerPage: 30,
202+
checked: !checked,
203+
query: "",
204+
});
205+
this.loadDataFromServer();
206+
}
137207
render() {
138-
const { data, error, columns, query, PlaceHolder,
139-
currentPage, recordsPerPage, isLoading
208+
const { error, hasMore, isLoading, data, columns, query, PlaceHolder,
209+
currentPage, recordsPerPage, checked
140210
} = this.state;
141211

142212
const indexOfLastRecord = currentPage * recordsPerPage;
@@ -163,13 +233,15 @@ class RecordTable extends PureComponent {
163233
placeholder={PlaceHolder}
164234
onChange={this.tableSearchFilter}
165235
/>
236+
<div id="checkbox">
237+
<input
238+
type="checkbox"
239+
id="checkBox"
240+
onClick={this.handleCheckBox}
241+
defaultChecked="true" /> <strong>Change Data</strong>
242+
</div>
166243
</form>
167244

168-
if (isLoading) {
169-
return (
170-
<Preloader />
171-
);
172-
}
173245
if (error) {
174246
return (
175247
<div className="error">
@@ -179,23 +251,25 @@ class RecordTable extends PureComponent {
179251
</div>
180252
);
181253
}
254+
182255
return (
183-
<div>
184-
{recordFilter}
185-
<table id="dataTable">
186-
<TableHeaders columns={columns} columnSort={this.columnSort} />
187-
{
188-
tableData.map((record, key) => {
189-
return (
190-
<TableRows
191-
key={key}
192-
columns={columns}
193-
data={record}
194-
/>
195-
);
196-
})
197-
}
198-
</table>
256+
<div>
257+
{recordFilter}
258+
<table id="dataTable">
259+
<TableHeaders columns={columns} checked={checked} columnSort={this.columnSort} />
260+
{
261+
tableData.map((record, key) => {
262+
return (
263+
<TableRows
264+
key={key}
265+
columns={columns}
266+
data={record}
267+
checked={checked}
268+
/>
269+
);
270+
})
271+
}
272+
</table>
199273
<Pagination
200274
data={data}
201275
recordsPerPage={recordsPerPage}
@@ -206,7 +280,9 @@ class RecordTable extends PureComponent {
206280
handleLast={this.handleLast}
207281
handleIncrement={this.handleIncrement}
208282
/>
209-
</div>
283+
{isLoading && <Preloader />}
284+
{!hasMore && <ScrollButton />}
285+
</div>
210286
)
211287
}
212288
}

src/Components/expandable-item.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React, { PureComponent } from "react";
2+
3+
class ExpandableItem extends PureComponent {
4+
constructor(props) {
5+
super(props);
6+
this.state = {
7+
error: false,
8+
isExpanded: this.props.expanded,
9+
isLoading: false,
10+
}
11+
}
12+
13+
render() {
14+
const { data, columns, getDescendantProp } = this.props;
15+
16+
return(
17+
<tr>
18+
{
19+
columns && columns.map((column, key) => {
20+
return (
21+
<td key={key}>
22+
{getDescendantProp(data, column.Value)}
23+
</td>
24+
);
25+
})
26+
27+
}
28+
</tr>
29+
);
30+
}
31+
}
32+
33+
export default ExpandableItem;

src/Components/scroll-to-top.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React, { PureComponent } from "react";
2+
3+
class ScrollButton extends PureComponent {
4+
scrollToTop = () => {
5+
window.scrollTo(0, 0);
6+
};
7+
render() {
8+
return (
9+
<footer>
10+
<button title="Back to top" onClick={this.scrollToTop}>Back to top</button>
11+
</footer>
12+
);
13+
}
14+
}
15+
16+
export default ScrollButton;

0 commit comments

Comments
 (0)