All files / src/providers PaginationProvider.js

90.91% Statements 20/22
68.75% Branches 11/16
87.5% Functions 7/8
90.48% Lines 19/21
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 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 50 51 52 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 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155                      1x         1x 1x                     1x     1x 1x 1x         1x                     2x       2x                                                                                                                   2x   2x     2x     2x   2x                           2x   1x           1x             2x        
/* eslint-disable react/no-unused-prop-types */
import PropTypes from "prop-types";
import React from "react";
import { connect } from "react-redux";
 
import * as types from "../constants/ActionTypes";
 
import { ConnectedResourceProvider as ResourceProvider } from "./ResourceProvider";
 
export class PaginationProvider extends React.Component {
  componentWillMount() {
    this.setup();
  }
 
  // sets the default page on load
  setup() {
    const { setCurrentPage, currentPage } = this.props;
    setCurrentPage(currentPage);
  }
 
  render() {
    const {
      setPageTotal,
      resourceUrl,
      render,
      resource,
      totalPages,
      totalPagesResolver,
    } = this.props;
 
    // Set Page total once response becomes available
    Eif (!resource.meta.loading) {
      const newPageTotal = totalPagesResolver(resource.response);
      Iif (newPageTotal !== totalPages) {
        setPageTotal(newPageTotal);
      }
    }
 
    return (
      <ResourceProvider
        endpoint={resourceUrl}
        render={(renderResource, renderMeta) =>
          render(renderResource, renderMeta)
        }
      />
    );
  }
}
 
PaginationProvider.defaultProps = {
  defaultPage: 1,
};
 
PaginationProvider.propTypes = {
  /**
   * The key for storing data in redux. Will be used for saving and fetching
   * data.
   */
  handle: PropTypes.string.isRequired,
 
  /**
   * The function for determining the url, based on the current URL
   */
  resolve: PropTypes.func.isRequired,
 
  /**
   * Dispatch function for setting total pages
   */
  setPageTotal: PropTypes.func.isRequired,
 
  /**
   * Dispatch function for setting current page
   */
  setCurrentPage: PropTypes.func.isRequired,
 
  /**
   * Current Page Number
   */
  currentPage: PropTypes.number,
 
  /**
   * The default page number to load
   */
  defaultPage: PropTypes.number,
 
  /**
   * The method for determining total pages from response
   */
  totalPagesResolver: PropTypes.func.isRequired,
 
  /**
   * Total Number of pages
   */
  totalPages: PropTypes.string,
 
  /**
   * The current resource URL
   */
  resourceUrl: PropTypes.string.isRequired,
 
  /**
   * The actual resource object. To be used for rendering the page.
   */
  resource: PropTypes.object.isRequired,
 
  /**
   * Func to be rendered once the resource comes back
   */
  render: PropTypes.func.isRequired,
};
 
export const mapStateToProps = (state, ownProps) => {
  const pageData =
    state.horsemanPaginations && state.horsemanPaginations[ownProps.handle]
      ? state.horsemanPaginations[ownProps.handle]
      : {};
  const currentPage = pageData.currentPage
    ? pageData.currentPage
    : ownProps.defaultPage;
  const resourceUrl = ownProps.resolve(currentPage);
 
  return {
    currentPage,
    totalPages: pageData.totalPages && pageData.totalPages,
    resourceUrl,
    resource:
      state.horsemanResources && state.horsemanResources[resourceUrl]
        ? state.horsemanResources[resourceUrl]
        : { meta: { loading: true, error: false }, data: {} },
  };
};
 
/**
 * The component needs to be able to fetch the resource we want.
 */
export const mapDispatchToProps = (dispatch, ownProps) => ({
  setPageTotal: totalPages =>
    dispatch({
      data: { totalPages },
      handle: ownProps.handle,
      type: types.SET_PAGE_TOTAL,
    }),
  setCurrentPage: currentPage =>
    dispatch({
      data: { currentPage },
      handle: ownProps.handle,
      type: types.SET_CURRENT_PAGE,
    }),
});
 
export const ConnectedPaginationProvider = connect(
  mapStateToProps,
  mapDispatchToProps,
)(PaginationProvider);