UNPKG

5.53 kBJSXView Raw
1// @flow
2/* eslint-disable */
3
4type Settings = {
5 key: string;
6 rowsPerLoad: number;
7 manipulateItems: (items: any) => void;
8 resetView: (data : any) => void;
9 changeView: (data: any) => void;
10 requestPage: (page: string, token : string) => any;
11}
12
13type OwnProps = {
14 token: string;
15 settings: Settings;
16};
17
18type LoadPaginatorPropTypes = {
19 token: string;
20 children: any;
21 settings: Settings;
22 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;
38};
39
40import React, { Component } from "react";
41import * as Immutable from "immutable";
42import { connect } from "react-redux";
43import { bindActionCreators } from "redux";
44
45import selectors from "./selectors";
46
47import LoadingButton from "./LoadingButton";
48
49import { LargeErrorMessage, LoadingMessage } from "x25/Messages";
50import words from "./words";
51
52const mapStateToProps = (state, { token, settings } : OwnProps) => {
53
54 const { list, entities } = selectors.getPaginators(state, settings.key);
55
56 const
57 currentPage = selectors.getCurrentView(list, token),
58 isFetching = selectors.isPageFetching(list, token, currentPage),
59 isFetched = selectors.isPageFetched(list, token, currentPage),
60 isNextFetching = selectors.isPageFetching(list, token, currentPage + 1),
61 isNextFetched = selectors.isPageFetched(list, token, currentPage + 1),
62 resultsUpTo = (
63 selectors.getResultsUpToPage(list, token, entities, currentPage, settings.rowsPerLoad)
64 ),
65 items = settings.manipulateItems(resultsUpTo),
66 total = selectors.getCurrentTotalResultsCount(list, token),
67 hasProblems = selectors.hasPageProblems(list, token, currentPage);
68
69 const shouldLoadNext = !isNextFetched && !isNextFetching;
70
71 return {
72 paginator: Immutable.Map({
73 currentPage,
74 hasProblems,
75 isFetched,
76 isFetching,
77 items,
78 shouldLoadNext,
79 total,
80 }),
81 };
82 },
83 mapDispatchToProps = (dispatch, { token, settings } : OwnProps) => ({
84 ...bindActionCreators({
85 resetView : settings.resetView,
86 changeView : settings.changeView,
87 }, dispatch),
88 loadData (page) {
89 dispatch(settings.requestPage(page, token));
90 },
91 });
92
93class LoadPaginator extends Component<LoadPaginatorPropTypes> {
94
95 handleLoadMoreClick: () => void;
96
97 constructor (props : LoadPaginatorPropTypes) {
98 super(props);
99
100 this.handleLoadMoreClick = () => {
101 const { paginator, token, changeView, loadData } = this.props;
102
103 const
104 currentPage = paginator.get("currentPage"),
105 hasProblems = paginator.get("hasProblems"),
106 shouldLoadNext = paginator.get("shouldLoadNext");
107
108 if (hasProblems) {
109 loadData(currentPage);
110 } else {
111 changeView({
112 token,
113 view: currentPage + 1,
114 });
115
116 if (shouldLoadNext) {
117 loadData(currentPage + 1);
118 }
119 }
120 };
121 }
122
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 );
157 }
158
159 componentWillUnmount () {
160 this.props.resetView(this.props.token);
161 }
162
163 render () {
164 const { paginator } = this.props;
165
166 const
167 items = paginator.get("items"),
168 hasProblems = paginator.get("hasProblems"),
169 currentPage = paginator.get("currentPage"),
170 isFetching = paginator.get("isFetching"),
171 total = paginator.get("total");
172
173 const
174 isEmpty = items.size === 0,
175 showLoading = total !== items.size;
176
177 if (isEmpty && isFetching) {
178 return (
179 <LoadingMessage message={words.LoadingData} />
180 );
181 }
182
183 if (hasProblems && currentPage === 1) {
184 return (
185 <LargeErrorMessage
186 message={words.ThereWasAProblem}
187 onRetry={this.handleLoadMoreClick}
188 />
189 );
190 }
191
192 return (
193 <React.Fragment>
194 {React.cloneElement(this.props.children, this.props)}
195 {
196 showLoading ? (
197 <LoadingButton
198 hasProblems={hasProblems}
199 isFetching={isFetching}
200 onLoadMoreClick={this.handleLoadMoreClick}
201 />
202 ) : null
203 }
204 </React.Fragment>
205 );
206 }
207}
208
209export default connect(mapStateToProps, mapDispatchToProps)(LoadPaginator);