redux-paginator-immutable 17.0.4 → 17.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/lib/__tests__/createPaginator.spec.js +2 -2
  2. package/lib/__tests__/reducers.spec.js +2 -3
  3. package/lib/__tests__/selectors.spec.js +11 -13
  4. package/package.json +15 -8
  5. package/src/Info.tsx +29 -0
  6. package/src/LoadDataItem.tsx +84 -0
  7. package/src/{LoadPaginator.jsx → LoadPaginator.tsx} +77 -94
  8. package/src/LoadingButton.tsx +40 -0
  9. package/src/__tests__/createPaginator.spec.js +6 -6
  10. package/src/__tests__/reducers.spec.js +28 -28
  11. package/src/__tests__/selectors.spec.js +80 -81
  12. package/src/{actionTypes.js → actionTypes.ts} +0 -4
  13. package/src/actions.ts +157 -0
  14. package/src/agent.ts +62 -0
  15. package/src/createDataReducer.ts +98 -0
  16. package/src/{createItemReducer.js → createItemReducer.ts} +6 -12
  17. package/src/createPaginator.ts +107 -0
  18. package/src/{index.js → index.ts} +0 -13
  19. package/src/paginatorMiddleware.ts +93 -0
  20. package/src/reducerItemData.ts +74 -0
  21. package/src/reducerOperations.ts +101 -0
  22. package/src/{reducers.js → reducers.ts} +9 -18
  23. package/src/selectors.ts +113 -0
  24. package/src/types/{actions.js → actions.ts} +27 -39
  25. package/src/types/{index.js → index.ts} +3 -13
  26. package/src/types/{state.js → state.ts} +3 -6
  27. package/src/util.ts +51 -0
  28. package/src/{words.js → words.ts} +0 -2
  29. package/lib/Info.js +0 -37
  30. package/lib/LoadDataItem.js +0 -110
  31. package/lib/LoadPaginator.js +0 -216
  32. package/lib/LoadingButton.js +0 -75
  33. package/lib/actionTypes.js +0 -16
  34. package/lib/actions.js +0 -136
  35. package/lib/agent.js +0 -86
  36. package/lib/createDataReducer.js +0 -83
  37. package/lib/createItemReducer.js +0 -36
  38. package/lib/createPaginator.js +0 -141
  39. package/lib/index.js +0 -58
  40. package/lib/paginatorMiddleware.js +0 -102
  41. package/lib/reducerItemData.js +0 -63
  42. package/lib/reducerOperations.js +0 -114
  43. package/lib/reducers.js +0 -87
  44. package/lib/selectors.js +0 -129
  45. package/lib/types/actions.js +0 -1
  46. package/lib/types/index.js +0 -29
  47. package/lib/types/state.js +0 -1
  48. package/lib/util.js +0 -73
  49. package/lib/words.js +0 -15
  50. package/src/Info.jsx +0 -32
  51. package/src/LoadDataItem.jsx +0 -116
  52. package/src/LoadingButton.jsx +0 -55
  53. package/src/actions.js +0 -153
  54. package/src/agent.js +0 -55
  55. package/src/createDataReducer.js +0 -94
  56. package/src/createPaginator.js +0 -131
  57. package/src/paginatorMiddleware.js +0 -94
  58. package/src/reducerItemData.jsx +0 -64
  59. package/src/reducerOperations.jsx +0 -112
  60. package/src/selectors.js +0 -143
  61. package/src/util.js +0 -71
@@ -22,8 +22,8 @@ describe("createPaginator", function () {
22
22
  idKey: "id_field",
23
23
  resultsKey: "results",
24
24
  totalKey: "count"
25
- });
26
- var action = paginator.requestPage(42, "foo=bar");
25
+ }),
26
+ action = paginator.requestPage(42, "foo=bar");
27
27
 
28
28
  (0, _expect2.default)(action).toEqual(requestPage({
29
29
  endpoint: "some/api/endpoint",
@@ -36,9 +36,8 @@ var requestPageAction = requestPage({
36
36
  idKey: "id",
37
37
  page: 2,
38
38
  token: "foo=bar"
39
- });
40
-
41
- var receivePageAction = receivePage({
39
+ }),
40
+ receivePageAction = receivePage({
42
41
  endpoint: "some/api/endpoint/",
43
42
  pageArgName: "p",
44
43
  idKey: "id",
@@ -8,14 +8,14 @@ var _chaiImmutable = require("chai-immutable");
8
8
 
9
9
  var _chaiImmutable2 = _interopRequireDefault(_chaiImmutable);
10
10
 
11
- var _selectors = require("../selectors");
12
-
13
- var _selectors2 = _interopRequireDefault(_selectors);
14
-
15
11
  var _immutable = require("immutable");
16
12
 
17
13
  var Immutable = _interopRequireWildcard(_immutable);
18
14
 
15
+ var _selectors = require("../selectors");
16
+
17
+ var _selectors2 = _interopRequireDefault(_selectors);
18
+
19
19
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
20
20
 
21
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -29,10 +29,8 @@ var getCurrentTotalResultsCount = _selectors2.default.getCurrentTotalResultsCoun
29
29
  getResultsUpToPage = _selectors2.default.getResultsUpToPage,
30
30
  isPageFetched = _selectors2.default.isPageFetched,
31
31
  isPageFetching = _selectors2.default.isPageFetching,
32
- getCurrentView = _selectors2.default.getCurrentView;
33
-
34
-
35
- var paginator = Immutable.Map({
32
+ getCurrentView = _selectors2.default.getCurrentView,
33
+ paginator = Immutable.Map({
36
34
  "foo=bar": Immutable.Map({
37
35
  page: 3,
38
36
  token: "foo=bar",
@@ -51,9 +49,8 @@ var paginator = Immutable.Map({
51
49
  total: 17,
52
50
  view: 1
53
51
  })
54
- });
55
-
56
- var items = Immutable.Map({
52
+ }),
53
+ items = Immutable.Map({
57
54
  "1": Immutable.Map({
58
55
  data: "foo1",
59
56
  id: 1
@@ -92,9 +89,10 @@ var items = Immutable.Map({
92
89
  })
93
90
  });
94
91
 
92
+
95
93
  describe("selectors", function () {
96
94
 
97
- it("getAllResults shoud select all the items ids for pages with same params than the current page", function () {
95
+ it("getAllResults should select all the items ids for pages with same params than the current page", function () {
98
96
  (0, _chai.expect)(getAllResults(paginator, "foo=bar", items)).to.equal(Immutable.List([Immutable.Map({
99
97
  data: "foo1",
100
98
  id: 1
@@ -116,7 +114,7 @@ describe("selectors", function () {
116
114
  })]));
117
115
  });
118
116
 
119
- it("getResultsUpToPage shoud select all the items ids for pages with same params than the current page", function () {
117
+ it("getResultsUpToPage should select all the items ids for pages with same params than the current page", function () {
120
118
  (0, _chai.expect)(getResultsUpToPage(paginator, "foo=bar", items, 2, 2)).to.equal(Immutable.List([Immutable.Map({
121
119
  data: "foo1",
122
120
  id: 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "redux-paginator-immutable",
3
- "version": "17.0.4",
3
+ "version": "17.0.18",
4
4
  "description": "redux-paginator-immutable helps you deal with paginated API by composing your existing reducers",
5
5
  "main": "./lib/index.js",
6
6
  "babel": {
@@ -37,12 +37,13 @@
37
37
  "build": "npm run build:lib",
38
38
  "clean": "rimraf dist lib",
39
39
  "check": "npm-check -u -i babel-jest -i jest --specials=bin,eslint,babel,webpack",
40
- "eslint": "eslint --ext .jsx,.js src --fix",
41
- "load": "npm run test && npm run eslint && npm run clean && npm run build && npm publish",
42
- "test": "mocha --require babel-core/register --recursive --recursive \"src/**/__tests__/*\" --require src/__tests__/setup.js",
40
+ "eslint": "eslint --ext .jsx,.js,.ts,.tsx src --fix",
41
+ "load": "npm run test && npm run ts && npm run eslint && npm run clean && npm run build && npm publish",
42
+ "test": "ts-mocha src/__tests__/*.spec.js",
43
43
  "test:watch": "npm test -- --watch",
44
44
  "test:cov": "babel-node ./node_modules/isparta/bin/isparta cover ./node_modules/mocha/bin/_mocha -- --recursive \"src/**/__tests__/*\" --require src/__tests__/setup.js",
45
- "test:codecov": "cat ./coverage/coverage.json | ./node_modules/.bin/codecov"
45
+ "test:codecov": "cat ./coverage/coverage.json | ./node_modules/.bin/codecov",
46
+ "ts": "tsc --build --clean"
46
47
  },
47
48
  "repository": {
48
49
  "type": "git",
@@ -70,6 +71,9 @@
70
71
  },
71
72
  "homepage": "https://github.com/cristian-sima/redux-paginator-immutable#readme",
72
73
  "devDependencies": {
74
+ "@types/superagent": "^4.1.15",
75
+ "@typescript-eslint/eslint-plugin": "^5.10.2",
76
+ "@typescript-eslint/parser": "^5.10.2",
73
77
  "babel-cli": "^6.26.0",
74
78
  "babel-eslint": "^10.1.0",
75
79
  "babel-plugin-transform-decorators-legacy": "^1.3.5",
@@ -83,19 +87,22 @@
83
87
  "codecov": "^3.8.1",
84
88
  "cross-env": "^6.0.3",
85
89
  "es3ify": "^0.2.2",
86
- "eslint": "^6.7.0",
90
+ "eslint": "^8.8.0",
91
+ "eslint-plugin-import": "^2.25.4",
87
92
  "eslint-plugin-react": "^7.23.1",
88
93
  "expect": "^24.9.0",
89
- "flow-bin": "^0.148.0",
90
94
  "flux-standard-action": "^2.1.1",
91
95
  "glob": "^7.1.6",
92
96
  "isparta": "^4.1.1",
93
97
  "mocha": "^6.2.2",
94
98
  "npm-check": "^5.9.2",
95
99
  "rimraf": "^3.0.2",
100
+ "ts-mocha": "^9.0.2",
101
+ "typescript": "^4.5.5",
96
102
  "webpack": "^4.41.2"
97
103
  },
98
104
  "dependencies": {
105
+ "create-subscription": "^17.0.0",
99
106
  "depcheck": "^1.4.3",
100
107
  "immutable": "*",
101
108
  "query-string": "^7.1.0",
@@ -103,6 +110,6 @@
103
110
  "redux": "^4.1.2",
104
111
  "reselect": "^4.1.5",
105
112
  "superagent": "^7.1.1",
106
- "x25": "^17.0.15"
113
+ "x25": "^17.0.16"
107
114
  }
108
115
  }
package/src/Info.tsx ADDED
@@ -0,0 +1,29 @@
1
+ type InfoPropTypes = {
2
+ shown: number;
3
+ total: number;
4
+ one: string;
5
+ all: string;
6
+ };
7
+
8
+ import React from "react";
9
+ import { words as x25Words } from "x25/utility";
10
+ import words from "./words";
11
+
12
+ const
13
+ getNumberForm = (value: number, one: string, all: string): string => {
14
+ if (value === 1) {
15
+ return `1 ${one}`;
16
+ }
17
+
18
+ return `${x25Words.getNumberTense(value)} ${all}`;
19
+ },
20
+
21
+ Info = ({ shown, total, one, all }: InfoPropTypes) => (
22
+ <div className="text-muted">
23
+ {`${words.Showing} `}
24
+ {shown === total ? `${words.All} - ` : `${shown} ${words.Of}`}
25
+ {` ${getNumberForm(total, one, all)}`}
26
+ </div>
27
+ );
28
+
29
+ export default Info;
@@ -0,0 +1,84 @@
1
+ import * as React from "react";
2
+
3
+ type LoadDataItemPropTypes = {
4
+ isFetching: boolean;
5
+ fetched: boolean;
6
+ id: string;
7
+ hasError: boolean;
8
+ data: any;
9
+ children: React.ReactNode;
10
+ shouldFetch: any;
11
+ fetchItem: () => void;
12
+ };
13
+ type OwnProps = {
14
+ id: string;
15
+ settings: {
16
+ selectors: any;
17
+ dataItemURL: string;
18
+ endpoint: string;
19
+ manageEntity: any;
20
+ normalizeDataItem: any;
21
+ };
22
+ };
23
+ import { connect } from "react-redux";
24
+ import { LargeErrorMessage, LoadingMessage } from "x25/Messages";
25
+ import { fetchItem as fetchItemAction } from "./actions";
26
+ import words from "./words";
27
+
28
+ const
29
+ mapStateToProps = (state: any, {
30
+ settings: {
31
+ selectors,
32
+ },
33
+ id,
34
+ }: OwnProps) => ({
35
+ data : selectors.getItem(state, id),
36
+ hasError : selectors.getItemHasError(state, id),
37
+ fetched : selectors.getItemIsFetched(state, id),
38
+ isFetching : selectors.getIsFetchingItemInfo(state, id),
39
+ shouldFetch : selectors.getShouldFetchItemInfo(state, id),
40
+ }),
41
+ mapDispatchToProps = (dispatch: any, {
42
+ id,
43
+ settings,
44
+ }: OwnProps) => ({
45
+ fetchItem () {
46
+ dispatch(fetchItemAction({
47
+ ...settings,
48
+ id,
49
+ }));
50
+ },
51
+ }),
52
+
53
+ LoadDataItem = (props: LoadDataItemPropTypes) : any => {
54
+ const {
55
+ children,
56
+ data,
57
+ isFetching,
58
+ shouldFetch,
59
+ hasError,
60
+ fetchItem,
61
+ } = props;
62
+
63
+ React.useEffect(() => {
64
+ if (shouldFetch) {
65
+ fetchItem();
66
+ }
67
+ }, [shouldFetch, isFetching, hasError]);
68
+
69
+ if (isFetching) {
70
+ return <LoadingMessage message={words.LoadingData} />;
71
+ }
72
+
73
+ if (hasError) {
74
+ return <LargeErrorMessage message={words.ThereWasAProblem} onRetry={fetchItem} />;
75
+ }
76
+
77
+ if (data.size === 0) {
78
+ return null;
79
+ }
80
+
81
+ return children;
82
+ };
83
+
84
+ export default connect(mapStateToProps, mapDispatchToProps)(LoadDataItem);
@@ -1,72 +1,59 @@
1
- // @flow
2
- /* eslint-disable */
1
+
2
+ import React, { Component } from "react";
3
+ import * as Immutable from "immutable";
4
+ import { connect } from "react-redux";
5
+ import { bindActionCreators } from "redux";
6
+ import { LargeErrorMessage, LoadingMessage } from "x25/Messages";
7
+ import selectors from "./selectors";
8
+ import LoadingButton from "./LoadingButton";
9
+ import words from "./words";
3
10
 
4
11
  type Settings = {
5
12
  key: string;
6
13
  rowsPerLoad: number;
7
14
  manipulateItems: (items: any) => void;
8
- resetView: (data : any) => void;
15
+ resetView: (data: any) => void;
9
16
  changeView: (data: any) => void;
10
- requestPage: (page: string, token : string) => any;
11
- }
12
-
17
+ requestPage: (page: string, token: string) => any;
18
+ };
13
19
  type OwnProps = {
14
20
  token: string;
15
21
  settings: Settings;
16
22
  };
17
-
18
23
  type LoadPaginatorPropTypes = {
19
24
  token: string;
20
25
  children: any;
21
26
  settings: Settings;
22
27
  paginator: any;
23
- // {
24
- // currentPage,
25
- // isFetching,
26
- // isFetched,
27
- // shouldLoadNext,
28
- // items,
29
- // hasProblems,
30
- // total,
31
- // }
32
-
33
- changeView: (info : { token: string, view: number }) => void;
34
- resetView: (token : string) => void;
35
-
36
- loadData: (page : number) => void;
37
- changeFilter: (filter : string) => (event : { target : { value : string } }) => void;
28
+ changeView: (info: {
29
+ token: string;
30
+ view: number;
31
+ }) => void;
32
+ resetView: (token: string) => void;
33
+ loadData: (page: number) => void;
34
+ changeFilter: (filter: string) => (event: {
35
+ target: {
36
+ value: string;
37
+ };
38
+ }) => void;
38
39
  };
39
40
 
40
- import React, { Component } from "react";
41
- import * as Immutable from "immutable";
42
- import { connect } from "react-redux";
43
- import { bindActionCreators } from "redux";
44
-
45
- import selectors from "./selectors";
46
-
47
- import LoadingButton from "./LoadingButton";
48
-
49
- import { LargeErrorMessage, LoadingMessage } from "x25/Messages";
50
- import words from "./words";
51
-
52
- const mapStateToProps = (state, { token, settings } : OwnProps) => {
53
-
54
- const { list, entities } = selectors.getPaginators(state, settings.key);
55
-
41
+ const
42
+ mapStateToProps = (state : any, { token, settings }: OwnProps) => {
56
43
  const
44
+ { list, entities } = selectors.getPaginators(state, settings.key),
57
45
  currentPage = selectors.getCurrentView(list, token),
58
46
  isFetching = selectors.isPageFetching(list, token, currentPage),
59
47
  isFetched = selectors.isPageFetched(list, token, currentPage),
60
48
  isNextFetching = selectors.isPageFetching(list, token, currentPage + 1),
61
49
  isNextFetched = selectors.isPageFetched(list, token, currentPage + 1),
62
- resultsUpTo = (
63
- selectors.getResultsUpToPage(list, token, entities, currentPage, settings.rowsPerLoad)
64
- ),
50
+ // eslint-disable-next-line max-len
51
+ resultsUpTo = selectors.getResultsUpToPage(list, token, entities, currentPage, settings.rowsPerLoad),
65
52
  items = settings.manipulateItems(resultsUpTo),
66
53
  total = selectors.getCurrentTotalResultsCount(list, token),
67
- hasProblems = selectors.hasPageProblems(list, token, currentPage);
68
-
69
- const shouldLoadNext = !isNextFetched && !isNextFetching;
54
+ // currentPage was previously given to the following function
55
+ hasProblems = selectors.hasPageProblems(list, token),
56
+ shouldLoadNext = !isNextFetched && !isNextFetching;
70
57
 
71
58
  return {
72
59
  paginator: Immutable.Map({
@@ -80,27 +67,59 @@ const mapStateToProps = (state, { token, settings } : OwnProps) => {
80
67
  }),
81
68
  };
82
69
  },
83
- mapDispatchToProps = (dispatch, { token, settings } : OwnProps) => ({
70
+ mapDispatchToProps = (dispatch : any, {
71
+ token,
72
+ settings,
73
+ }: OwnProps) => ({
84
74
  ...bindActionCreators({
85
75
  resetView : settings.resetView,
86
76
  changeView : settings.changeView,
87
77
  }, dispatch),
88
- loadData (page) {
78
+ loadData (page : any) {
89
79
  dispatch(settings.requestPage(page, token));
90
80
  },
91
81
  });
92
82
 
83
+
84
+ // new
85
+
86
+ /* eslint-disable */
93
87
  class LoadPaginator extends Component<LoadPaginatorPropTypes> {
94
88
 
95
- handleLoadMoreClick: () => void;
89
+ handleLoadMoreClick: () => any;
90
+
91
+ componentDidMount () {
92
+ const
93
+ { paginator, loadData } = this.props,
94
+ isFetched = paginator.get("isFetched"),
95
+ isFetching = paginator.get("isFetching"),
96
+ currentPage = paginator.get("currentPage"),
97
+ shouldFetch = !isFetched && !isFetching;
98
+
99
+ if (shouldFetch) {
100
+ loadData(currentPage);
101
+ }
102
+ }
103
+
104
+ UNSAFE_componentWillReceiveProps (nextProps : LoadPaginatorPropTypes) {
105
+ const
106
+ { loadData, paginator } = nextProps,
107
+ isFetched = paginator.get("isFetched"),
108
+ isFetching = paginator.get("isFetching"),
109
+ currentPage = paginator.get("currentPage"),
110
+ shouldFetch = !isFetched && !isFetching;
96
111
 
97
- constructor (props : LoadPaginatorPropTypes) {
112
+ if (shouldFetch) {
113
+ loadData(currentPage);
114
+ }
115
+ }
116
+
117
+ constructor (props: LoadPaginatorPropTypes) {
98
118
  super(props);
99
119
 
100
120
  this.handleLoadMoreClick = () => {
101
- const { paginator, token, changeView, loadData } = this.props;
102
-
103
121
  const
122
+ { paginator, token, changeView, loadData } = this.props,
104
123
  currentPage = paginator.get("currentPage"),
105
124
  hasProblems = paginator.get("hasProblems"),
106
125
  shouldLoadNext = paginator.get("shouldLoadNext");
@@ -120,40 +139,8 @@ class LoadPaginator extends Component<LoadPaginatorPropTypes> {
120
139
  };
121
140
  }
122
141
 
123
- UNSAFE_componentWillMount () {
124
- const { paginator, loadData } = this.props;
125
-
126
- const
127
- isFetched = paginator.get("isFetched"),
128
- isFetching = paginator.get("isFetching"),
129
- currentPage = paginator.get("currentPage");
130
-
131
- const shouldFetch = !isFetched && !isFetching;
132
-
133
- if (shouldFetch) {
134
- loadData(currentPage);
135
- }
136
- }
137
-
138
- UNSAFE_componentWillReceiveProps (nextProps) {
139
- const { loadData, paginator } = nextProps;
140
-
141
- const
142
- isFetched = paginator.get("isFetched"),
143
- isFetching = paginator.get("isFetching"),
144
- currentPage = paginator.get("currentPage");
145
-
146
- const shouldFetch = !isFetched && !isFetching;
147
-
148
- if (shouldFetch) {
149
- loadData(currentPage);
150
- }
151
- }
152
-
153
- shouldComponentUpdate (nextProps : LoadPaginatorPropTypes) {
154
- return (
155
- this.props.paginator !== nextProps.paginator
156
- );
142
+ shouldComponentUpdate (nextProps: LoadPaginatorPropTypes) {
143
+ return this.props.paginator !== nextProps.paginator;
157
144
  }
158
145
 
159
146
  componentWillUnmount () {
@@ -161,23 +148,18 @@ class LoadPaginator extends Component<LoadPaginatorPropTypes> {
161
148
  }
162
149
 
163
150
  render () {
164
- const { paginator } = this.props;
165
-
166
151
  const
152
+ { paginator } = this.props,
167
153
  items = paginator.get("items"),
168
154
  hasProblems = paginator.get("hasProblems"),
169
155
  currentPage = paginator.get("currentPage"),
170
156
  isFetching = paginator.get("isFetching"),
171
- total = paginator.get("total");
172
-
173
- const
157
+ total = paginator.get("total"),
174
158
  isEmpty = items.size === 0,
175
159
  showLoading = total !== items.size;
176
160
 
177
161
  if (isEmpty && isFetching) {
178
- return (
179
- <LoadingMessage message={words.LoadingData} />
180
- );
162
+ return <LoadingMessage message={words.LoadingData} />;
181
163
  }
182
164
 
183
165
  if (hasProblems && currentPage === 1) {
@@ -190,7 +172,7 @@ class LoadPaginator extends Component<LoadPaginatorPropTypes> {
190
172
  }
191
173
 
192
174
  return (
193
- <React.Fragment>
175
+ <>
194
176
  {React.cloneElement(this.props.children, this.props)}
195
177
  {
196
178
  showLoading ? (
@@ -201,9 +183,10 @@ class LoadPaginator extends Component<LoadPaginatorPropTypes> {
201
183
  />
202
184
  ) : null
203
185
  }
204
- </React.Fragment>
186
+ </>
205
187
  );
206
188
  }
189
+
207
190
  }
208
191
 
209
192
  export default connect(mapStateToProps, mapDispatchToProps)(LoadPaginator);
@@ -0,0 +1,40 @@
1
+ import React from "react";
2
+ import { ErrorMessage, LoadingMessage } from "x25/Messages";
3
+
4
+ type LoadingButtonPropTypes = {
5
+ isFetching: boolean;
6
+ hasProblems: boolean;
7
+ onLoadMoreClick: () => void;
8
+ };
9
+ import words from "./words";
10
+
11
+ class LoadingButton extends React.Component<LoadingButtonPropTypes> {
12
+
13
+ shouldComponentUpdate (nextProps: LoadingButtonPropTypes) {
14
+ const { hasProblems, isFetching } = this.props;
15
+
16
+ return hasProblems !== nextProps.hasProblems || isFetching !== nextProps.isFetching;
17
+ }
18
+
19
+ render () {
20
+ const { isFetching, hasProblems, onLoadMoreClick } = this.props;
21
+
22
+ return (
23
+ <div className="text-center my-2">
24
+ {hasProblems ? <ErrorMessage message={words.ThereWasAProblem} /> : null}
25
+ {isFetching ? <LoadingMessage message={words.LoadingData} sm /> : (
26
+ <button
27
+ className="btn btn-outline-info d-print-none"
28
+ disabled={isFetching}
29
+ onClick={onLoadMoreClick}
30
+ type="button">
31
+ {isFetching ? words.LoadingData : words.LoadMore}
32
+ </button>
33
+ )}
34
+ </div>
35
+ );
36
+ }
37
+
38
+ }
39
+
40
+ export default LoadingButton;
@@ -16,12 +16,12 @@ describe("createPaginator", () => {
16
16
 
17
17
  it("should create correct request action creator", () => {
18
18
  const paginator = createPaginator("some/api/endpoint", {
19
- pageArgName : "p",
20
- idKey : "id_field",
21
- resultsKey : "results",
22
- totalKey : "count",
23
- });
24
- const action = paginator.requestPage(42, "foo=bar");
19
+ pageArgName : "p",
20
+ idKey : "id_field",
21
+ resultsKey : "results",
22
+ totalKey : "count",
23
+ }),
24
+ action = paginator.requestPage(42, "foo=bar");
25
25
 
26
26
  expect(action).
27
27
  toEqual(requestPage({
@@ -20,33 +20,33 @@ import {
20
20
  } from "../reducers";
21
21
 
22
22
  const requestPageAction = requestPage({
23
- endpoint : "some/api/endpoint",
24
- resultsKey : "results",
25
- totalKey : "total",
26
- pageArgName : "p",
27
- idKey : "id",
28
- page : 2,
29
- token : "foo=bar",
30
- });
31
-
32
- const receivePageAction = receivePage({
33
- endpoint : "some/api/endpoint/",
34
- pageArgName : "p",
35
- idKey : "id",
36
- page : 2,
37
- token : "foo=bar",
38
- items : [
39
- {
40
- id : "baz",
41
- fooField : "bazValue",
42
- },
43
- {
44
- id : "bar",
45
- fooField : "barValue",
46
- },
47
- ],
48
- total: 2,
49
- });
23
+ endpoint : "some/api/endpoint",
24
+ resultsKey : "results",
25
+ totalKey : "total",
26
+ pageArgName : "p",
27
+ idKey : "id",
28
+ page : 2,
29
+ token : "foo=bar",
30
+ }),
31
+
32
+ receivePageAction = receivePage({
33
+ endpoint : "some/api/endpoint/",
34
+ pageArgName : "p",
35
+ idKey : "id",
36
+ page : 2,
37
+ token : "foo=bar",
38
+ items : [
39
+ {
40
+ id : "baz",
41
+ fooField : "bazValue",
42
+ },
43
+ {
44
+ id : "bar",
45
+ fooField : "barValue",
46
+ },
47
+ ],
48
+ total: 2,
49
+ });
50
50
 
51
51
  describe("pages reducer", () => {
52
52
 
@@ -76,7 +76,7 @@ describe("pages reducer", () => {
76
76
  view : 1,
77
77
  fetched : false,
78
78
  }),
79
- })
79
+ }),
80
80
  );
81
81
  });
82
82