<commit_before>import _ from 'lodash';
import React from 'react';
import { css } from 'glamor';
import withSize from 'react-sizeme';
import { compose, withPropsOnChange, defaultProps, withProps } from 'recompose';

import Pagination from 'components/Pagination';
import styles from './ListPane.styles';

interface IListProps {
  onSelect: Function;
  Component: any;
  getKey: Function;
  getData: Function;
  size: any;
  pageSize: number;
  styles: any;
  selectedItem: any;
}

interface IListState {
  items: any[];
  count: number;
  offset: number;
}

const enhance = compose(
  defaultProps({
    columnWidth: 200,
    rowHeight: 60,
    getKey: item => item.id,
  }),
  withSize({
    refreshRate: 20,
    monitorHeight: true,
  }),
  withProps(({ columnWidth, rowHeight }) => ({
    styles: styles({ columnWidth, rowHeight }),
  })),
  withPropsOnChange(
    (props, nextProps) =>
      (props.size.width !== nextProps.size.width || props.size.height !== nextProps.size.height) &&
      nextProps.size.width !== 0,
    ({ size, columnWidth, rowHeight }) => {
      // TODO: move this HOC into the element that only renders the list, no extra elements to account for
      const extraVerticalSpace = 60;
      const extraHorizontalSpace = 20;
      const columns = Math.max(Math.floor((size.width - extraHorizontalSpace) / columnWidth), 1);
      const rows = Math.max(Math.floor((size.height - extraVerticalSpace) / rowHeight), 1);
      const pageSize = columns * rows;
      return {
        pageSize,
      };
    },
  ),
);

class List extends React.Component<IListProps, IListState> {
  state = {
    items: [],
    count: 0,
    offset: 0,
  };

  fetchData = async () => {
    const { getData, pageSize } = this.props;
    const { offset } = this.state;
    const { resultSet, count = 0 } = await getData({ offset, limit: pageSize });
    this.setState({ items: resultSet, count });
  };

  componentDidMount() {
    this.fetchData();
  }

  componentDidUpdate(prevProps: IListProps, prevState: IListState) {
    if (prevProps.pageSize !== this.props.pageSize || prevState.offset !== this.state.offset) {
      this.fetchData();
    }
  }

  render() {
    const { onSelect, Component, getKey, pageSize, styles, selectedItem } = this.props;
    const { items, count, offset } = this.state;

    const fillersRequired = pageSize - items.length;

    return (
      <div className={`List ${css(styles.container)}`}>
        <div className={`items-wrapper`}>
          {items.map(item => (
            <Component
              className={selectedItem && getKey(item) === getKey(selectedItem) ? 'selected' : ''}
              item={item}
              style={styles.listItem}<commit_msg>accept styles prop in listpane<commit_after>import _ from 'lodash';
import React from 'react';
import { css } from 'glamor';
import withSize from 'react-sizeme';
import { compose, withPropsOnChange, defaultProps, withProps } from 'recompose';

import Pagination from 'components/Pagination';
import styles from './ListPane.styles';

interface IListProps {
  onSelect: Function;
  Component: any;
  getKey: Function;
  getData: Function;
  size: any;
  pageSize: number;
  styles: any;
  selectedItem: any;
}

interface IListState {
  items: any[];
  count: number;
  offset: number;
}

const enhance = compose(
  defaultProps({
    columnWidth: 200,
    rowHeight: 60,
    getKey: item => item.id,
    onSelect: _.noop,
  }),
  withSize({
    refreshRate: 20,
    monitorHeight: true,
  }),
  withProps(({ columnWidth, rowHeight, styles: stylesProp }) => ({
    styles: _.merge(styles({ columnWidth, rowHeight }), [stylesProp]),
  })),
  withPropsOnChange(
    (props, nextProps) =>
      (props.size.width !== nextProps.size.width || props.size.height !== nextProps.size.height) &&
      nextProps.size.width !== 0,
    ({ size, columnWidth, rowHeight }) => {
      // TODO: move this HOC into the element that only renders the list, no extra elements to account for
      const extraVerticalSpace = 60;
      const extraHorizontalSpace = 20;
      const columns = Math.max(Math.floor((size.width - extraHorizontalSpace) / columnWidth), 1);
      const rows = Math.max(Math.floor((size.height - extraVerticalSpace) / rowHeight), 1);
      const pageSize = columns * rows;
      return {
        pageSize,
      };
    },
  ),
);

class List extends React.Component<IListProps, IListState> {
  state = {
    items: [],
    count: 0,
    offset: 0,
  };

  fetchData = async () => {
    const { getData, pageSize } = this.props;
    const { offset } = this.state;
    const { resultSet, count = 0 } = await getData({ offset, limit: pageSize });
    this.setState({ items: resultSet, count });
  };

  componentDidMount() {
    this.fetchData();
  }

  componentDidUpdate(prevProps: IListProps, prevState: IListState) {
    if (
      prevProps.pageSize !== this.props.pageSize ||
      prevState.offset !== this.state.offset ||
      prevProps.getData !== this.props.getData
    ) {
      this.fetchData();
    }
  }

  render() {
    const { onSelect, Component, getKey, pageSize, styles, selectedItem } = this.props;
    const { items, count, offset } = this.state;

    const fillersRequired = pageSize - items.length;

    return (
      <div className={`List ${css(styles.container)}`}>
        <div className={`items-wrapper`}>
          {items.map(item => (
            <Component
              className={selectedItem && getKey(item) === getKey(selectedItem) ? 'selected' : ''}
              item={item}
              style={styles.listItem}
{'fraction_non_alphanumeric': 0.13721601153984853, 'fraction_numerical': 0.006130544536602957, 'mean_word_length': 3.057790782735918, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6523325', 'n_tokens_mistral': 1723, 'n_tokens_neox': 1674, 'n_words': 430}