Advertisement
Guest User

Untitled

a guest
Nov 20th, 2017
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { PureComponent, PropTypes } from 'react';
  2. import { connect } from 'react-redux';
  3.  
  4. import { Alert } from 'antd';
  5.  
  6. import _debounce from 'lodash/debounce';
  7.  
  8. import {
  9.   Serialize,
  10.   multiPushInUrlQuery,
  11.   UrlQueryParamTypes,
  12.   addUrlProps
  13. } from 'react-url-query';
  14.  
  15. import { getAuthors } from 'store/modules/entities/authors';
  16. import { Authors } from 'store/selectors';
  17.  
  18. import { LetteringTabs } from 'components/next';
  19. import { getCleanFirstLetter } from 'utils/utils';
  20.  
  21. import styles from './styles.less';
  22.  
  23.  
  24. @addUrlProps({
  25.   mapUrlToProps: url => ({
  26.     author: Serialize.decode(UrlQueryParamTypes.number, url.author),
  27.   }),
  28.   mapUrlChangeHandlersToProps: () => ({
  29.     pushToQuery: ({ author }) => multiPushInUrlQuery({
  30.       author: author ? Serialize.encode(UrlQueryParamTypes.number, author) : null,
  31.       book: null,
  32.       page: null,
  33.       size: null,
  34.       object: null,
  35.       objectType: null
  36.     })
  37.   })
  38. })
  39. @connect((state, { author }) => ({
  40.   items: Authors.list(state),
  41.   authorEntity: Authors.data(state)[author],
  42.   loading: Authors.meta(state).loading,
  43.   error: Authors.meta(state).error,
  44.   last: Authors.meta(state).latest,
  45.   itemsBySearch: Authors.lastList(state)
  46. }), { getAuthors })
  47. class RepositoryAuthorListContainer extends PureComponent {
  48.   static propTypes = {
  49.     getAuthors: PropTypes.func.isRequired,
  50.     pushToQuery: PropTypes.func.isRequired,
  51.     items: PropTypes.array,
  52.     itemsBySearch: PropTypes.array,
  53.     author: PropTypes.number,
  54.     authorEntity: PropTypes.object,
  55.     loading: PropTypes.bool,
  56.     error: PropTypes.oneOfType([
  57.       PropTypes.bool,
  58.       PropTypes.object
  59.     ])
  60.   }
  61.  
  62.   static defaultProps = {
  63.     items: [],
  64.     itemsBySearch: [],
  65.     author: null,
  66.     authorEntity: null,
  67.     loading: false,
  68.     error: false
  69.   }
  70.  
  71.   state = {
  72.     letter: null,
  73.     search: null
  74.   }
  75.  
  76.   componentWillMount() {
  77.     this.props.getAuthors();
  78.  
  79.     const { authorEntity } = this.props;
  80.  
  81.     if (authorEntity) {
  82.       this.setState({
  83.         search: authorEntity.name,
  84.         letter: getCleanFirstLetter(authorEntity.name)
  85.       });
  86.     }
  87.   }
  88.  
  89.   componentWillReceiveProps(nextProps) {
  90.     const { authorEntity } = nextProps;
  91.  
  92.     if (authorEntity) {
  93.       this.setState({
  94.         letter: getCleanFirstLetter(authorEntity.name),
  95.         search: authorEntity.name
  96.       });
  97.     } else {
  98.       this.setState({
  99.         search: this.props.authorEntity ? null : this.state.search
  100.       });
  101.     }
  102.   }
  103.  
  104.   onLetterChange = (letter) => {
  105.     this.setState({ letter });
  106.   }
  107.  
  108.   onSearch = (value) => {
  109.     this.setState({
  110.       search: value
  111.     }, () => {
  112.       if (value) {
  113.         this.fetchOnMatch({ match: value });
  114.       } else if (this.props.author) {
  115.         this.props.pushToQuery({
  116.           author: null,
  117.         });
  118.       }
  119.     });
  120.   }
  121.  
  122.   fetchOnMatch = _debounce(this.props.getAuthors, 300);
  123.  
  124.   renderItem = (item) => {
  125.     const { author } = this.props;
  126.  
  127.     return (
  128.       <div key={item.id} className={styles.item}>
  129.         <a
  130.           href={`?author=${item.id}`}
  131.           onClick={(e) => {
  132.             e.preventDefault();
  133.             if (item.id === author) {
  134.               return false;
  135.             }
  136.             return this.props.pushToQuery({ author: item.id });
  137.           }}>
  138.           {this.renderInBold(item.name, item.id === author)}
  139.         </a>
  140.       </div>
  141.     );
  142.   }
  143.  
  144.   renderInBold = (text, inBold) => {
  145.     return (inBold ? <strong>{text}</strong> : (text));
  146.   }
  147.  
  148.   render() {
  149.     const {
  150.       items,
  151.       itemsBySearch,
  152.       loading,
  153.       error,
  154.       author
  155.     } = this.props;
  156.  
  157.     const showLoader = items.length === 0 && loading === true;
  158.     const nativeSearch = this.state.search && !author;
  159.  
  160.     const itemsBySearchIds = itemsBySearch.map(i => i.id);
  161.     const filterSearchItems = item => itemsBySearchIds.includes(item.id);
  162.  
  163.     return (
  164.       <div className={styles.component}>
  165.         {showLoader ? (
  166.           'Loading..'
  167.         ) : (
  168.           !error && (
  169.             <LetteringTabs
  170.               className={styles.tabs}
  171.               items={items}
  172.               searchValue={this.state.search}
  173.               searchDisabled={!!author}
  174.               onSearch={this.onSearch}
  175.               filterSearchItems={filterSearchItems}
  176.               activeLetter={this.state.letter}
  177.               onLetterChange={this.onLetterChange}
  178.               getLetterFromItem={item => getCleanFirstLetter(item.name)}
  179.               filterItemsByLetter={(item, letter) => getCleanFirstLetter(item.name) === letter}
  180.               sortItems={(a, b) => a.name.localeCompare(b.name)}
  181.               renderItem={this.renderItem}
  182.               showSearchTab={nativeSearch}
  183.               maxSearchItems={10}
  184.               nothingFoundText={loading ? null : (
  185.                 <Alert message="No authors found" />
  186.               )}
  187.             />
  188.           )
  189.         )}
  190.         {error ? (
  191.           <Alert
  192.             type="error"
  193.             message={
  194.               <span>
  195.                 Failed to load authors. <a
  196.                   href=""
  197.                   onClick={(e) => {
  198.                     e.preventDefault();
  199.                     this.props.getAuthors();
  200.                   }} >Retry.</a>
  201.               </span>
  202.             } />
  203.         ) : null}
  204.       </div>
  205.     );
  206.   }
  207. }
  208.  
  209. export default RepositoryAuthorListContainer;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement