redux-paginator-immutable 17.0.16 → 17.0.21
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.
- package/lib/Info.d.ts +9 -0
- package/lib/Info.js +19 -41
- package/lib/Info.js.map +1 -0
- package/lib/LoadDataItem.d.ts +23 -0
- package/lib/LoadDataItem.js +59 -110
- package/lib/LoadDataItem.js.map +1 -0
- package/lib/LoadPaginator.d.ts +41 -0
- package/lib/LoadPaginator.js +109 -216
- package/lib/LoadPaginator.js.map +1 -0
- package/lib/LoadingButton.d.ts +11 -0
- package/lib/LoadingButton.js +22 -75
- package/lib/LoadingButton.js.map +1 -0
- package/lib/actionTypes.d.ts +9 -0
- package/lib/actionTypes.js +13 -16
- package/lib/actionTypes.js.map +1 -0
- package/lib/actions.d.ts +42 -0
- package/lib/actions.js +82 -136
- package/lib/actions.js.map +1 -0
- package/lib/agent.d.ts +8 -0
- package/lib/agent.js +37 -86
- package/lib/agent.js.map +1 -0
- package/lib/createDataReducer.d.ts +14 -0
- package/lib/createDataReducer.js +60 -79
- package/lib/createDataReducer.js.map +1 -0
- package/lib/createItemReducer.d.ts +9 -0
- package/lib/createItemReducer.js +14 -32
- package/lib/createItemReducer.js.map +1 -0
- package/lib/createPaginator.d.ts +14 -0
- package/lib/createPaginator.js +83 -140
- package/lib/createPaginator.js.map +1 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +30 -58
- package/lib/index.js.map +1 -0
- package/lib/paginatorMiddleware.d.ts +5 -0
- package/lib/paginatorMiddleware.js +68 -102
- package/lib/paginatorMiddleware.js.map +1 -0
- package/lib/reducerItemData.d.ts +18 -0
- package/lib/reducerItemData.js +56 -63
- package/lib/reducerItemData.js.map +1 -0
- package/lib/reducerOperations.d.ts +3 -0
- package/lib/reducerOperations.js +69 -114
- package/lib/reducerOperations.js.map +1 -0
- package/lib/reducers.d.ts +4 -0
- package/lib/reducers.js +75 -87
- package/lib/reducers.js.map +1 -0
- package/lib/selectors.d.ts +58 -0
- package/lib/selectors.js +79 -129
- package/lib/selectors.js.map +1 -0
- package/lib/types/actions.d.ts +85 -0
- package/lib/types/actions.js +3 -1
- package/lib/types/actions.js.map +1 -0
- package/lib/types/index.d.ts +21 -0
- package/lib/types/index.js +16 -29
- package/lib/types/index.js.map +1 -0
- package/lib/types/state.d.ts +6 -0
- package/lib/types/state.js +3 -1
- package/lib/types/state.js.map +1 -0
- package/lib/util.d.ts +9 -0
- package/lib/util.js +49 -73
- package/lib/util.js.map +1 -0
- package/lib/words.d.ts +9 -0
- package/lib/words.js +12 -15
- package/lib/words.js.map +1 -0
- package/package.json +35 -21
- package/src/Info.tsx +29 -0
- package/src/LoadDataItem.tsx +84 -0
- package/src/{LoadPaginator.jsx → LoadPaginator.tsx} +77 -94
- package/src/LoadingButton.tsx +40 -0
- package/src/__tests__/createPaginator.spec.js +6 -6
- package/src/__tests__/reducers.spec.js +28 -28
- package/src/__tests__/selectors.spec.js +80 -81
- package/src/{actionTypes.js → actionTypes.ts} +0 -4
- package/src/actions.ts +157 -0
- package/src/agent.ts +62 -0
- package/src/createDataReducer.ts +91 -0
- package/src/{createItemReducer.js → createItemReducer.ts} +7 -13
- package/src/createPaginator.ts +107 -0
- package/src/{index.js → index.ts} +0 -13
- package/src/paginatorMiddleware.ts +93 -0
- package/src/reducerItemData.ts +74 -0
- package/src/reducerOperations.ts +101 -0
- package/src/{reducers.js → reducers.ts} +9 -18
- package/src/selectors.ts +113 -0
- package/src/types/{actions.js → actions.ts} +27 -39
- package/src/types/{index.js → index.ts} +6 -13
- package/src/types/{state.js → state.ts} +3 -6
- package/src/util.ts +51 -0
- package/src/{words.js → words.ts} +0 -2
- package/lib/__tests__/actions.spec.js +0 -117
- package/lib/__tests__/agent.spec.js +0 -32
- package/lib/__tests__/createPaginator.spec.js +0 -39
- package/lib/__tests__/reducers.spec.js +0 -126
- package/lib/__tests__/selectors.spec.js +0 -162
- package/lib/__tests__/setup.js +0 -3
- package/src/Info.jsx +0 -34
- package/src/LoadDataItem.jsx +0 -116
- package/src/LoadingButton.jsx +0 -55
- package/src/actions.js +0 -153
- package/src/agent.js +0 -55
- package/src/createDataReducer.js +0 -94
- package/src/createPaginator.js +0 -131
- package/src/paginatorMiddleware.js +0 -94
- package/src/reducerItemData.jsx +0 -64
- package/src/reducerOperations.jsx +0 -112
- package/src/selectors.js +0 -143
- package/src/util.js +0 -71
|
@@ -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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
|
@@ -5,93 +5,92 @@ import chaiImmutable from "chai-immutable";
|
|
|
5
5
|
|
|
6
6
|
chai.use(chaiImmutable);
|
|
7
7
|
|
|
8
|
-
import selectors from "../selectors";
|
|
9
|
-
|
|
10
|
-
const {
|
|
11
|
-
getCurrentTotalResultsCount,
|
|
12
|
-
getAllResults,
|
|
13
|
-
getResultsUpToPage,
|
|
14
|
-
isPageFetched,
|
|
15
|
-
isPageFetching,
|
|
16
|
-
getCurrentView,
|
|
17
|
-
} = selectors;
|
|
18
|
-
|
|
19
8
|
import * as Immutable from "immutable";
|
|
9
|
+
import selectors from "../selectors";
|
|
20
10
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
11
|
+
const
|
|
12
|
+
{
|
|
13
|
+
getCurrentTotalResultsCount,
|
|
14
|
+
getAllResults,
|
|
15
|
+
getResultsUpToPage,
|
|
16
|
+
isPageFetched,
|
|
17
|
+
isPageFetching,
|
|
18
|
+
getCurrentView,
|
|
19
|
+
} = selectors,
|
|
20
|
+
paginator = Immutable.Map({
|
|
21
|
+
"foo=bar": Immutable.Map({
|
|
22
|
+
page : 3,
|
|
23
|
+
token : "foo=bar",
|
|
24
|
+
ids : Immutable.List([
|
|
25
|
+
1,
|
|
26
|
+
2,
|
|
27
|
+
3,
|
|
28
|
+
7,
|
|
29
|
+
8,
|
|
30
|
+
9,
|
|
31
|
+
]),
|
|
32
|
+
total : 42,
|
|
33
|
+
view : 2,
|
|
34
|
+
fetching : false,
|
|
35
|
+
fetched : true,
|
|
36
|
+
}),
|
|
37
|
+
"foo=baz": Immutable.Map({
|
|
38
|
+
page : 1,
|
|
39
|
+
token : "foo=baz",
|
|
40
|
+
ids : Immutable.List([
|
|
41
|
+
1,
|
|
42
|
+
4,
|
|
43
|
+
6,
|
|
44
|
+
]),
|
|
45
|
+
fetching : false,
|
|
46
|
+
fetched : true,
|
|
47
|
+
total : 17,
|
|
48
|
+
view : 1,
|
|
49
|
+
}),
|
|
50
50
|
}),
|
|
51
|
-
});
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
52
|
+
items = Immutable.Map({
|
|
53
|
+
"1": Immutable.Map({
|
|
54
|
+
data : "foo1",
|
|
55
|
+
id : 1,
|
|
56
|
+
}),
|
|
57
|
+
"2": Immutable.Map({
|
|
58
|
+
data : "foo2",
|
|
59
|
+
id : 2,
|
|
60
|
+
}),
|
|
61
|
+
"3": Immutable.Map({
|
|
62
|
+
data : "foo3",
|
|
63
|
+
id : 3,
|
|
64
|
+
}),
|
|
65
|
+
"4": Immutable.Map({
|
|
66
|
+
data : "foo4",
|
|
67
|
+
id : 4,
|
|
68
|
+
}),
|
|
69
|
+
"5": Immutable.Map({
|
|
70
|
+
data : "foo5",
|
|
71
|
+
id : 5,
|
|
72
|
+
}),
|
|
73
|
+
"6": Immutable.Map({
|
|
74
|
+
data : "foo6",
|
|
75
|
+
id : 6,
|
|
76
|
+
}),
|
|
77
|
+
"7": Immutable.Map({
|
|
78
|
+
data : "foo7",
|
|
79
|
+
id : 7,
|
|
80
|
+
}),
|
|
81
|
+
"8": Immutable.Map({
|
|
82
|
+
data : "foo8",
|
|
83
|
+
id : 8,
|
|
84
|
+
}),
|
|
85
|
+
"9": Immutable.Map({
|
|
86
|
+
data : "foo9",
|
|
87
|
+
id : 9,
|
|
88
|
+
}),
|
|
89
|
+
});
|
|
91
90
|
|
|
92
91
|
describe("selectors", () => {
|
|
93
92
|
|
|
94
|
-
it("getAllResults
|
|
93
|
+
it("getAllResults should select all the items ids for pages with same params than the current page", () => {
|
|
95
94
|
expect(getAllResults(paginator, "foo=bar", items)).
|
|
96
95
|
to.equal(Immutable.List([
|
|
97
96
|
Immutable.Map({
|
|
@@ -121,7 +120,7 @@ describe("selectors", () => {
|
|
|
121
120
|
]));
|
|
122
121
|
});
|
|
123
122
|
|
|
124
|
-
it("getResultsUpToPage
|
|
123
|
+
it("getResultsUpToPage should select all the items ids for pages with same params than the current page", () => {
|
|
125
124
|
expect(getResultsUpToPage(paginator, "foo=bar", items, 2, 2)).
|
|
126
125
|
to.equal(Immutable.List([
|
|
127
126
|
Immutable.Map({
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
1
|
export const REQUEST_PAGE = "@@redux-paginator-immutable/REQUEST_PAGE";
|
|
4
2
|
export const RECEIVE_PAGE = "@@redux-paginator-immutable/RECEIVE_PAGE";
|
|
5
3
|
export const RESET_VIEW = "@@redux-paginator-immutable/RESET_VIEW";
|
|
6
4
|
export const CHANGE_VIEW = "@@redux-paginator-immutable/CHANGE_VIEW";
|
|
7
5
|
export const CLEAR_DATA = "@@redux-paginator-immutable/CLEAR_DATA";
|
|
8
|
-
|
|
9
6
|
export const FETCH_ITEM_DATA_PENDING = "@@redux-paginator-immutable/FETCH_ITEM_DATA_PENDING";
|
|
10
7
|
export const FETCH_ITEM_DATA_REJECTED = "@@redux-paginator-immutable/FETCH_ITEM_DATA_REJECTED";
|
|
11
8
|
export const FETCH_ITEM_DATA_FULFILLED = "@@redux-paginator-immutable/FETCH_ITEM_DATA_FULFILLED";
|
|
12
|
-
|
|
13
9
|
export const FETCH_CURRENT_COMPANY_INFO_PENDING = "FETCH_CURRENT_COMPANY_INFO_PENDING";
|
package/src/actions.ts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
|
|
2
|
+
import agent from "superagent";
|
|
3
|
+
|
|
4
|
+
import type { Action, EndPointCb } from "./types";
|
|
5
|
+
|
|
6
|
+
type RequestPageArgsTypes = {
|
|
7
|
+
endpoint: string;
|
|
8
|
+
endpointCb: EndPointCb;
|
|
9
|
+
manageEntity: any;
|
|
10
|
+
resultsKey: string;
|
|
11
|
+
totalKey: string;
|
|
12
|
+
pageArgName: string;
|
|
13
|
+
idKey: string;
|
|
14
|
+
page: number;
|
|
15
|
+
token: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type ReceivePageArgsTypes = {
|
|
19
|
+
endpoint: string;
|
|
20
|
+
endpointCb: EndPointCb;
|
|
21
|
+
manageEntity: any;
|
|
22
|
+
pageArgName: string;
|
|
23
|
+
idKey: string;
|
|
24
|
+
page: number;
|
|
25
|
+
token: string;
|
|
26
|
+
items: Array<any>;
|
|
27
|
+
total: number;
|
|
28
|
+
error: boolean;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const requestPage = ({
|
|
32
|
+
endpoint,
|
|
33
|
+
endpointCb,
|
|
34
|
+
manageEntity,
|
|
35
|
+
resultsKey,
|
|
36
|
+
totalKey,
|
|
37
|
+
pageArgName,
|
|
38
|
+
idKey,
|
|
39
|
+
page,
|
|
40
|
+
token,
|
|
41
|
+
}: RequestPageArgsTypes): Action => ({
|
|
42
|
+
type : "@@redux-paginator-immutable/REQUEST_PAGE",
|
|
43
|
+
meta : {
|
|
44
|
+
endpoint,
|
|
45
|
+
endpointCb,
|
|
46
|
+
manageEntity,
|
|
47
|
+
resultsKey,
|
|
48
|
+
totalKey,
|
|
49
|
+
pageArgName,
|
|
50
|
+
idKey,
|
|
51
|
+
},
|
|
52
|
+
payload: {
|
|
53
|
+
page,
|
|
54
|
+
token,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
|
|
58
|
+
receivePage = ({
|
|
59
|
+
endpoint,
|
|
60
|
+
endpointCb,
|
|
61
|
+
manageEntity,
|
|
62
|
+
pageArgName,
|
|
63
|
+
idKey,
|
|
64
|
+
page,
|
|
65
|
+
token,
|
|
66
|
+
items,
|
|
67
|
+
error,
|
|
68
|
+
total,
|
|
69
|
+
}: ReceivePageArgsTypes): Action => ({
|
|
70
|
+
type : "@@redux-paginator-immutable/RECEIVE_PAGE",
|
|
71
|
+
meta : {
|
|
72
|
+
endpoint,
|
|
73
|
+
endpointCb,
|
|
74
|
+
manageEntity,
|
|
75
|
+
pageArgName,
|
|
76
|
+
idKey,
|
|
77
|
+
},
|
|
78
|
+
payload: {
|
|
79
|
+
page,
|
|
80
|
+
token,
|
|
81
|
+
items,
|
|
82
|
+
error,
|
|
83
|
+
total,
|
|
84
|
+
},
|
|
85
|
+
}),
|
|
86
|
+
|
|
87
|
+
resetView = (endpoint: string, token: string): Action => ({
|
|
88
|
+
type : "@@redux-paginator-immutable/RESET_VIEW",
|
|
89
|
+
meta : {
|
|
90
|
+
endpoint,
|
|
91
|
+
},
|
|
92
|
+
payload: {
|
|
93
|
+
token,
|
|
94
|
+
},
|
|
95
|
+
}),
|
|
96
|
+
|
|
97
|
+
changeView = (endpoint: string, {
|
|
98
|
+
token,
|
|
99
|
+
view,
|
|
100
|
+
}: {
|
|
101
|
+
token: string;
|
|
102
|
+
view: number;
|
|
103
|
+
}): Action => ({
|
|
104
|
+
type : "@@redux-paginator-immutable/CHANGE_VIEW",
|
|
105
|
+
meta : {
|
|
106
|
+
endpoint,
|
|
107
|
+
},
|
|
108
|
+
payload: {
|
|
109
|
+
token,
|
|
110
|
+
view,
|
|
111
|
+
},
|
|
112
|
+
}),
|
|
113
|
+
|
|
114
|
+
clearData = (endpoint: string): Action => ({
|
|
115
|
+
type : "@@redux-paginator-immutable/CLEAR_DATA",
|
|
116
|
+
meta : {
|
|
117
|
+
endpoint,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// data info
|
|
122
|
+
type FetchDataItem = {
|
|
123
|
+
dataItemURL: string;
|
|
124
|
+
endpoint: string;
|
|
125
|
+
normalizeDataItem: any;
|
|
126
|
+
id: string;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const fetchDataItemRequest = ({
|
|
130
|
+
dataItemURL,
|
|
131
|
+
normalizeDataItem,
|
|
132
|
+
id,
|
|
133
|
+
}: FetchDataItem): Promise<any> => (
|
|
134
|
+
new Promise((resolve, reject) => (
|
|
135
|
+
agent.
|
|
136
|
+
get(`${dataItemURL}/${id}`).
|
|
137
|
+
set("Accept", "application/json").
|
|
138
|
+
end(normalizeDataItem(resolve, reject))
|
|
139
|
+
)) as Promise<any>
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
export const fetchItem = (things: FetchDataItem): any => ({
|
|
143
|
+
type : "@@redux-paginator-immutable/FETCH_ITEM_DATA",
|
|
144
|
+
payload : fetchDataItemRequest(things),
|
|
145
|
+
meta : {
|
|
146
|
+
id : things.id,
|
|
147
|
+
endpoint : things.endpoint,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
export default {
|
|
152
|
+
clearData,
|
|
153
|
+
requestPage,
|
|
154
|
+
receivePage,
|
|
155
|
+
resetView,
|
|
156
|
+
changeView,
|
|
157
|
+
};
|
package/src/agent.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* eslint-disable no-bitwise*/
|
|
2
|
+
|
|
3
|
+
type FetchPageArgs = {
|
|
4
|
+
endpoint: string;
|
|
5
|
+
pageArgName: string;
|
|
6
|
+
page: number;
|
|
7
|
+
token: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
import agent from "superagent";
|
|
11
|
+
import qs from "query-string";
|
|
12
|
+
|
|
13
|
+
export const
|
|
14
|
+
buildSuffix = (pageArgName: string, page: number, params: string) => {
|
|
15
|
+
const parsedParams = qs.parse(params);
|
|
16
|
+
let finalParsedParams = {},
|
|
17
|
+
startString = "";
|
|
18
|
+
|
|
19
|
+
for (const key of Object.keys(parsedParams)) {
|
|
20
|
+
if (parsedParams[key] === null) {
|
|
21
|
+
startString += key;
|
|
22
|
+
} else {
|
|
23
|
+
finalParsedParams = { ...finalParsedParams,
|
|
24
|
+
[key]: parsedParams[key],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
startString = startString === "" ? "?" : `${startString}?`;
|
|
30
|
+
|
|
31
|
+
if (Object.keys(finalParsedParams).length > 0 && qs.extract(params) !== "") {
|
|
32
|
+
startString = params.replace(qs.extract(params), "");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return startString + qs.stringify({ ...finalParsedParams,
|
|
36
|
+
[pageArgName]: page,
|
|
37
|
+
}, {
|
|
38
|
+
encode: false,
|
|
39
|
+
}).replace(startString, "");
|
|
40
|
+
},
|
|
41
|
+
fetchPage = ({
|
|
42
|
+
endpoint,
|
|
43
|
+
pageArgName,
|
|
44
|
+
page,
|
|
45
|
+
token,
|
|
46
|
+
}: FetchPageArgs) => {
|
|
47
|
+
const suffix = buildSuffix(pageArgName, page, token),
|
|
48
|
+
url = endpoint + suffix,
|
|
49
|
+
promise: any = new Promise(
|
|
50
|
+
(resolve: any, reject: any) => (
|
|
51
|
+
agent.
|
|
52
|
+
get(url).
|
|
53
|
+
end((err: any, res: any) => err ? reject(err) : resolve(res))
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
return promise.then((res: {
|
|
58
|
+
body: any;
|
|
59
|
+
}) => ({
|
|
60
|
+
response: res.body,
|
|
61
|
+
}));
|
|
62
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* eslint-disable max-lines-per-function, */
|
|
2
|
+
import { createSelector } from "reselect";
|
|
3
|
+
import * as Immutable from "immutable";
|
|
4
|
+
import type { PaginatorSettings } from "./types";
|
|
5
|
+
|
|
6
|
+
type Selector = (state : any, id : string) => any;
|
|
7
|
+
type ListSelector = (state : any) => any;
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
Use to create a complex list where you need more information about
|
|
11
|
+
the item. For instance, if you DO need to fetch more data or to
|
|
12
|
+
manipulate it
|
|
13
|
+
*/
|
|
14
|
+
const
|
|
15
|
+
createDataReducer = ({ key }: PaginatorSettings) => {
|
|
16
|
+
const
|
|
17
|
+
getItems = (state: any) : any => (
|
|
18
|
+
state.getIn(["entities", key])
|
|
19
|
+
),
|
|
20
|
+
getItem : Selector = createSelector(
|
|
21
|
+
getItems,
|
|
22
|
+
(_state : any, id : string) => id,
|
|
23
|
+
(data : any, id : string) : any => data.get(id) || Immutable.Map(),
|
|
24
|
+
),
|
|
25
|
+
getItemsList : ListSelector = createSelector(
|
|
26
|
+
getItems,
|
|
27
|
+
(data : any) => data.map((current : any) => current.get("Data")).toList(),
|
|
28
|
+
),
|
|
29
|
+
getItemData : Selector = createSelector(
|
|
30
|
+
getItems,
|
|
31
|
+
(_state : any, id : string) => id,
|
|
32
|
+
(data : any, id : string) : any => {
|
|
33
|
+
if (typeof data === "undefined") {
|
|
34
|
+
return Immutable.Map();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return data.getIn([id, "Data"]);
|
|
38
|
+
},
|
|
39
|
+
),
|
|
40
|
+
getItemHasError : Selector = createSelector(
|
|
41
|
+
getItem,
|
|
42
|
+
(data : any) : boolean => {
|
|
43
|
+
if (typeof data === "undefined") {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return data.get("error") === true;
|
|
48
|
+
},
|
|
49
|
+
),
|
|
50
|
+
getIsFetchingItemInfo : Selector = createSelector(
|
|
51
|
+
getItem,
|
|
52
|
+
(data : any) : boolean => {
|
|
53
|
+
if (typeof data === "undefined") {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return data.get("fetching");
|
|
58
|
+
},
|
|
59
|
+
),
|
|
60
|
+
getItemIsFetched : Selector = createSelector(
|
|
61
|
+
getItem,
|
|
62
|
+
(data : any) : boolean => {
|
|
63
|
+
if (typeof data === "undefined") {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return data.get("fetched");
|
|
68
|
+
},
|
|
69
|
+
),
|
|
70
|
+
getShouldFetchItemInfo : Selector = createSelector(
|
|
71
|
+
getIsFetchingItemInfo,
|
|
72
|
+
getItemIsFetched,
|
|
73
|
+
getItemHasError,
|
|
74
|
+
(isFetching : boolean, isFetched : boolean, hasError : boolean) : boolean => (
|
|
75
|
+
!isFetched && !isFetching && !hasError
|
|
76
|
+
),
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
getItems,
|
|
81
|
+
getItem,
|
|
82
|
+
getItemsList,
|
|
83
|
+
getItemData,
|
|
84
|
+
getItemHasError,
|
|
85
|
+
getIsFetchingItemInfo,
|
|
86
|
+
getItemIsFetched,
|
|
87
|
+
getShouldFetchItemInfo,
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export default createDataReducer;
|
|
@@ -1,28 +1,22 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
import type { PaginatorSettings } from "./types";
|
|
4
|
-
|
|
5
1
|
import { createSelector } from "reselect";
|
|
2
|
+
import type { PaginatorSettings } from "./types";
|
|
6
3
|
|
|
7
4
|
/*
|
|
8
5
|
Use to create a simple list where you do not need more information about
|
|
9
6
|
the item. For instance, if you do NOT need to fetch more data or
|
|
10
7
|
manipulate it
|
|
11
8
|
*/
|
|
12
|
-
const createReducer = ({ key }
|
|
9
|
+
const createReducer = ({ key }: PaginatorSettings) => {
|
|
13
10
|
const
|
|
14
|
-
getItems = (state
|
|
15
|
-
|
|
16
|
-
key,
|
|
17
|
-
]),
|
|
18
|
-
getItem = createSelector(
|
|
11
|
+
getItems = (state: any) => state.getIn(["entities", key]),
|
|
12
|
+
getItem : (state : any, id : string) => any = createSelector(
|
|
19
13
|
getItems,
|
|
20
|
-
(
|
|
21
|
-
(data, id) => data.get(id)
|
|
14
|
+
(_state : any, id : string) => id,
|
|
15
|
+
(data : any, id : string) => data.get(id),
|
|
22
16
|
),
|
|
23
17
|
getItemsList = createSelector(
|
|
24
18
|
getItems,
|
|
25
|
-
(data) => data.toList()
|
|
19
|
+
(data : any) => data.toList(),
|
|
26
20
|
);
|
|
27
21
|
|
|
28
22
|
return {
|