UNPKG

5.51 kBJSXView Raw
1// @flow
2// /* eslint-disable no-unused-vars */
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";
50
51const mapStateToProps = (state, { token, settings } : OwnProps) => {
52
53 const { list, entities } = selectors.getPaginators(state, settings.key);
54
55 const
56 currentPage = selectors.getCurrentView(list, token),
57 isFetching = selectors.isPageFetching(list, token, currentPage),
58 isFetched = selectors.isPageFetched(list, token, currentPage),
59 isNextFetching = selectors.isPageFetching(list, token, currentPage + 1),
60 isNextFetched = selectors.isPageFetched(list, token, currentPage + 1),
61 resultsUpTo = (
62 selectors.getResultsUpToPage(list, token, entities, currentPage, settings.rowsPerLoad)
63 ),
64 items = settings.manipulateItems(resultsUpTo),
65 total = selectors.getCurrentTotalResultsCount(list, token),
66 hasProblems = selectors.hasPageProblems(list, token, currentPage);
67
68 const shouldLoadNext = !isNextFetched && !isNextFetching;
69
70 return {
71 paginator: Immutable.Map({
72 currentPage,
73 hasProblems,
74 isFetched,
75 isFetching,
76 items,
77 shouldLoadNext,
78 total,
79 }),
80 };
81 },
82 mapDispatchToProps = (dispatch, { token, settings } : OwnProps) => ({
83 ...bindActionCreators({
84 resetView : settings.resetView,
85 changeView : settings.changeView,
86 }, dispatch),
87 loadData (page) {
88 dispatch(settings.requestPage(page, token));
89 },
90 });
91
92class LoadPaginator extends Component<LoadPaginatorPropTypes> {
93
94 handleLoadMoreClick: () => void;
95
96 constructor (props : LoadPaginatorPropTypes) {
97 super(props);
98
99 this.handleLoadMoreClick = () => {
100 const { paginator, token, changeView, loadData } = this.props;
101
102 const
103 currentPage = paginator.get("currentPage"),
104 hasProblems = paginator.get("hasProblems"),
105 shouldLoadNext = paginator.get("shouldLoadNext");
106
107 if (hasProblems) {
108 loadData(currentPage);
109 } else {
110 changeView({
111 token,
112 view: currentPage + 1,
113 });
114
115 if (shouldLoadNext) {
116 loadData(currentPage + 1);
117 }
118 }
119 };
120 }
121
122 UNSAFE_componentWillMount () {
123 const { paginator, loadData } = this.props;
124
125 const
126 isFetched = paginator.get("isFetched"),
127 isFetching = paginator.get("isFetching"),
128 currentPage = paginator.get("currentPage");
129
130 const shouldFetch = !isFetched && !isFetching;
131
132 if (shouldFetch) {
133 loadData(currentPage);
134 }
135 }
136
137 UNSAFE_componentWillReceiveProps (nextProps) {
138 const { loadData, paginator } = nextProps;
139
140 const
141 isFetched = paginator.get("isFetched"),
142 isFetching = paginator.get("isFetching"),
143 currentPage = paginator.get("currentPage");
144
145 const shouldFetch = !isFetched && !isFetching;
146
147 if (shouldFetch) {
148 loadData(currentPage);
149 }
150 }
151
152 shouldComponentUpdate (nextProps : LoadPaginatorPropTypes) {
153 return (
154 this.props.paginator !== nextProps.paginator
155 );
156 }
157
158 componentWillUnmount () {
159 this.props.resetView(this.props.token);
160 }
161
162 render () {
163 const { paginator } = this.props;
164
165 const
166 items = paginator.get("items"),
167 hasProblems = paginator.get("hasProblems"),
168 currentPage = paginator.get("currentPage"),
169 isFetching = paginator.get("isFetching"),
170 total = paginator.get("total");
171
172 const
173 isEmpty = items.size === 0,
174 showLoading = total !== items.size;
175
176 if (isEmpty && isFetching) {
177 return (
178 <LoadingMessage message="Preiau datele..." />
179 );
180 }
181
182 if (hasProblems && currentPage === 1) {
183 return (
184 <LargeErrorMessage
185 message="Nu pot prelua datele"
186 onRetry={this.handleLoadMoreClick}
187 />
188 );
189 }
190
191 return (
192 <React.Fragment>
193 {React.cloneElement(this.props.children, this.props)}
194 {
195 showLoading ? (
196 <LoadingButton
197 hasProblems={hasProblems}
198 isFetching={isFetching}
199 onLoadMoreClick={this.handleLoadMoreClick}
200 />
201 ) : null
202 }
203 </React.Fragment>
204 );
205 }
206}
207
208export default connect(mapStateToProps, mapDispatchToProps)(LoadPaginator);