Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { PureComponent, PropTypes } from 'react';
- import { connect } from 'react-redux';
- import { Alert } from 'antd';
- import _debounce from 'lodash/debounce';
- import {
- Serialize,
- multiPushInUrlQuery,
- UrlQueryParamTypes,
- addUrlProps
- } from 'react-url-query';
- import { getAuthors } from 'store/modules/entities/authors';
- import { Authors } from 'store/selectors';
- import { LetteringTabs } from 'components/next';
- import { getCleanFirstLetter } from 'utils/utils';
- import styles from './styles.less';
- @addUrlProps({
- mapUrlToProps: url => ({
- author: Serialize.decode(UrlQueryParamTypes.number, url.author),
- }),
- mapUrlChangeHandlersToProps: () => ({
- pushToQuery: ({ author }) => multiPushInUrlQuery({
- author: author ? Serialize.encode(UrlQueryParamTypes.number, author) : null,
- book: null,
- page: null,
- size: null,
- object: null,
- objectType: null
- })
- })
- })
- @connect((state, { author }) => ({
- items: Authors.list(state),
- authorEntity: Authors.data(state)[author],
- loading: Authors.meta(state).loading,
- error: Authors.meta(state).error,
- last: Authors.meta(state).latest,
- itemsBySearch: Authors.lastList(state)
- }), { getAuthors })
- class RepositoryAuthorListContainer extends PureComponent {
- static propTypes = {
- getAuthors: PropTypes.func.isRequired,
- pushToQuery: PropTypes.func.isRequired,
- items: PropTypes.array,
- itemsBySearch: PropTypes.array,
- author: PropTypes.number,
- authorEntity: PropTypes.object,
- loading: PropTypes.bool,
- error: PropTypes.oneOfType([
- PropTypes.bool,
- PropTypes.object
- ])
- }
- static defaultProps = {
- items: [],
- itemsBySearch: [],
- author: null,
- authorEntity: null,
- loading: false,
- error: false
- }
- state = {
- letter: null,
- search: null
- }
- componentWillMount() {
- this.props.getAuthors();
- const { authorEntity } = this.props;
- if (authorEntity) {
- this.setState({
- search: authorEntity.name,
- letter: getCleanFirstLetter(authorEntity.name)
- });
- }
- }
- componentWillReceiveProps(nextProps) {
- const { authorEntity } = nextProps;
- if (authorEntity) {
- this.setState({
- letter: getCleanFirstLetter(authorEntity.name),
- search: authorEntity.name
- });
- } else {
- this.setState({
- search: this.props.authorEntity ? null : this.state.search
- });
- }
- }
- onLetterChange = (letter) => {
- this.setState({ letter });
- }
- onSearch = (value) => {
- this.setState({
- search: value
- }, () => {
- if (value) {
- this.fetchOnMatch({ match: value });
- } else if (this.props.author) {
- this.props.pushToQuery({
- author: null,
- });
- }
- });
- }
- fetchOnMatch = _debounce(this.props.getAuthors, 300);
- renderItem = (item) => {
- const { author } = this.props;
- return (
- <div key={item.id} className={styles.item}>
- <a
- href={`?author=${item.id}`}
- onClick={(e) => {
- e.preventDefault();
- if (item.id === author) {
- return false;
- }
- return this.props.pushToQuery({ author: item.id });
- }}>
- {this.renderInBold(item.name, item.id === author)}
- </a>
- </div>
- );
- }
- renderInBold = (text, inBold) => {
- return (inBold ? <strong>{text}</strong> : (text));
- }
- render() {
- const {
- items,
- itemsBySearch,
- loading,
- error,
- author
- } = this.props;
- const showLoader = items.length === 0 && loading === true;
- const nativeSearch = this.state.search && !author;
- const itemsBySearchIds = itemsBySearch.map(i => i.id);
- const filterSearchItems = item => itemsBySearchIds.includes(item.id);
- return (
- <div className={styles.component}>
- {showLoader ? (
- 'Loading..'
- ) : (
- !error && (
- <LetteringTabs
- className={styles.tabs}
- items={items}
- searchValue={this.state.search}
- searchDisabled={!!author}
- onSearch={this.onSearch}
- filterSearchItems={filterSearchItems}
- activeLetter={this.state.letter}
- onLetterChange={this.onLetterChange}
- getLetterFromItem={item => getCleanFirstLetter(item.name)}
- filterItemsByLetter={(item, letter) => getCleanFirstLetter(item.name) === letter}
- sortItems={(a, b) => a.name.localeCompare(b.name)}
- renderItem={this.renderItem}
- showSearchTab={nativeSearch}
- maxSearchItems={10}
- nothingFoundText={loading ? null : (
- <Alert message="No authors found" />
- )}
- />
- )
- )}
- {error ? (
- <Alert
- type="error"
- message={
- <span>
- Failed to load authors. <a
- href=""
- onClick={(e) => {
- e.preventDefault();
- this.props.getAuthors();
- }} >Retry.</a>
- </span>
- } />
- ) : null}
- </div>
- );
- }
- }
- export default RepositoryAuthorListContainer;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement