<commit_before>/*
 * Copyright 2019 EPAM Systems
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { injectIntl, defineMessages } from 'react-intl';
import PropTypes from 'prop-types';
import classNames from 'classnames/bind';
import {
  historyItemsSelector,
  activeLogIdSelector,
  NAMESPACE,
  NUMBER_OF_ITEMS_TO_LOAD,
  DEFAULT_HISTORY_DEPTH,
  HISTORY_DEPTH_LIMIT,
  fetchHistoryItemsAction,
} from 'controllers/log';
import { NOT_FOUND } from 'common/constants/testStatuses';
import { connectRouter } from 'common/utils';
import { PAGE_KEY, DEFAULT_PAGINATION } from 'controllers/pagination';
import { ScrollWrapper } from 'components/main/scrollWrapper';
import { SpinningPreloader } from 'components/preloaders/spinningPreloader';
import styles from './historyLine.scss';
import { HistoryLineItem } from './historyLineItem';

const cx = classNames.bind(styles);

const messages = defineMessages({
  loadMoreItemsTitle: {
    id: 'HistoryLine.loadMore',
    defaultMessage: '+{number} More',
  },
});

@connectRouter(
  undefined,
  {
    changeActiveItem: (itemId) => ({
      history: itemId,
      retryId: null,
      [PAGE_KEY]: DEFAULT_PAGINATION[PAGE_KEY],
    }),
  },
  { namespace: NAMESPACE },
)
@connect(
  (state) => ({
    historyItems: historyItemsSelector(state),
    activeItemId: activeLogIdSelector(state),
  }),
  {
    fetchHistoryItemsAction,
  },
)
@injectIntl
export class HistoryLine extends Component {
  constructor(props) {
    super(props);
    this.state = { isLoading: false };
  }
  static propTypes = {
    intl: PropTypes.object.isRequired,
    historyItems: PropTypes.array,
    activeItemId: PropTypes.number,
    changeActiveItem: PropTypes.func,
    fetchHistoryItemsAction: PropTypes.func,
  };

  static defaultProps = {
    historyItems: [],
    activeItemId: 0,
    changeActiveItem: () => {},
    fetchHistoryItemsAction: () => {},
  };

  checkIfTheItemLinkIsActive = (item) =>
    item.id !== this.props.activeItemId && item.status !== NOT_FOUND;

  finishLoading = () => {
    this.setState({ isLoading: false });
  };

  loadMoreItems = () => {
    if (this.state.isLoading) {
      return;
    }
    this.setState({ isLoading: true });
    this.props.fetchHistoryItemsAction(true, this.finishLoading);
  };

  render() {
    const { historyItems, activeItemId, changeActiveItem, intl } = this.props;
    const loadedItems = historyItems.length - DEFAULT_HISTORY_DEPTH;
    const shouldShowLoadMore =
      historyItems.length < HISTORY_DEPTH_LIMIT &&
      loadedItems >= 0 &&
      loadedItems % NUMBER_OF_ITEMS_TO_LOAD === 0;
    return (
      <div className={cx('history-line')}>
        <ScrollWrapper autoHeight hideTracksWhenNotNeeded initialScrollRight>
          <div className={cx('history-line-items')}>
            {shouldShowLoadMore && (
              <button className={cx('load-more')} onClick={this.loadMoreItems}>
                {this.state.isLoading ? (
                  <SpinningPreloader />
                ) : (
                  intl.formatMessage(messages.loadMoreItemsTitle, {
                    number: NUMBER_OF_ITEMS_TO_LOAD,
                  })
                )}
              </button>
            )}
            {historyItems.map((item, index) => (
              <HistoryLineItem
                key={item.id}
                active={item.id === activeItemId}
                isLastItem={index === historyItems.length - 1}
                onClick={() =>
                  this.checkIfTheItemLinkIsActive(item) ? changeActiveItem(item.id) : {}
                }<commit_msg>EPMRPP-60376 Fix history line load more for default history depth (#2609)<commit_after>/*
 * Copyright 2019 EPAM Systems
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { injectIntl, defineMessages } from 'react-intl';
import PropTypes from 'prop-types';
import classNames from 'classnames/bind';
import {
  historyItemsSelector,
  activeLogIdSelector,
  NAMESPACE,
  NUMBER_OF_ITEMS_TO_LOAD,
  DEFAULT_HISTORY_DEPTH,
  HISTORY_DEPTH_LIMIT,
  fetchHistoryItemsAction,
} from 'controllers/log';
import { NOT_FOUND } from 'common/constants/testStatuses';
import { connectRouter } from 'common/utils';
import { PAGE_KEY, DEFAULT_PAGINATION } from 'controllers/pagination';
import { ScrollWrapper } from 'components/main/scrollWrapper';
import { SpinningPreloader } from 'components/preloaders/spinningPreloader';
import styles from './historyLine.scss';
import { HistoryLineItem } from './historyLineItem';

const cx = classNames.bind(styles);

const messages = defineMessages({
  loadMoreItemsTitle: {
    id: 'HistoryLine.loadMore',
    defaultMessage: '+{number} More',
  },
});

@connectRouter(
  undefined,
  {
    changeActiveItem: (itemId) => ({
      history: itemId,
      retryId: null,
      [PAGE_KEY]: DEFAULT_PAGINATION[PAGE_KEY],
    }),
  },
  { namespace: NAMESPACE },
)
@connect(
  (state) => ({
    historyItems: historyItemsSelector(state),
    activeItemId: activeLogIdSelector(state),
  }),
  {
    fetchHistoryItemsAction,
  },
)
@injectIntl
export class HistoryLine extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: false,
      prevItemsCount: DEFAULT_HISTORY_DEPTH,
      shouldShowLoadMore: false,
    };
  }
  static propTypes = {
    intl: PropTypes.object.isRequired,
    historyItems: PropTypes.array,
    activeItemId: PropTypes.number,
    changeActiveItem: PropTypes.func,
    fetchHistoryItemsAction: PropTypes.func,
  };

  static defaultProps = {
    historyItems: [],
    activeItemId: 0,
    changeActiveItem: () => {},
    fetchHistoryItemsAction: () => {},
  };

  checkIfTheItemLinkIsActive = (item) =>
    item.id !== this.props.activeItemId && item.status !== NOT_FOUND;

  finishLoading = () => {
    const { historyItems } = this.props;
    const loadedItems = historyItems.length - DEFAULT_HISTORY_DEPTH;
    const shouldShowLoadMore =
      this.state.prevItemsCount !== historyItems.length &&
      historyItems.length < HISTORY_DEPTH_LIMIT &&
      loadedItems >= 0 &&
      loadedItems % NUMBER_OF_ITEMS_TO_LOAD === 0;
    this.setState({ isLoading: false, shouldShowLoadMore });
  };

  loadMoreItems = () => {
    const { historyItems } = this.props;
    if (this.state.isLoading) {
      return;
    }
    this.setState({ isLoading: true, prevItemsCount: historyItems.length });
    this.props.fetchHistoryItemsAction(true, this.finishLoading);
  };

  componentDidMount() {
    const { historyItems } = this.props;
    const loadedItems = historyItems.length - DEFAULT_HISTORY_DEPTH;
    this.setState({ shouldShowLoadMore: loadedItems === 0 });
  }

  render() {
    const { historyItems, activeItemId, changeActiveItem, intl } = this.props;
    return (
      <div className={cx('history-line')}>
        <ScrollWrapper autoHeight hideTracksWhenNotNeeded initialScrollRight>
          <div className={cx('history-line-items')}>
            {this.state.shouldShowLoadMore && (
              <button className={cx('load-more')} onClick={this.loadMoreItems}>
                {this.state.isLoading ? (
                  <SpinningPreloader />
                ) : (
                  intl.formatMessage(messages.loadMoreItemsTitle, {
                    number: NUMBER_OF_ITEMS_TO_LOAD,
                  })
                )}
              </button>
            )}
            {historyItems.map((item, index) => (
              <HistoryLineItem
                key={item.id}
                active={item.id === activeItemId}
                isLastItem={index === historyItems.length - 1}
                onClick={() =>
                  this.checkIfTheItemLinkIsActive(item) ? changeActiveItem(item.id) : {}
                }
{'fraction_non_alphanumeric': 0.11440153135908118, 'fraction_numerical': 0.0038283977029613782, 'mean_word_length': 3.0649885583524026, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '1084313', 'n_tokens_mistral': 2610, 'n_tokens_neox': 2555, 'n_words': 587}