<commit_before>import React from 'react';
import PropTypes from 'prop-types';

import TreeStatusModel from '../../models/treeStatus';
import BugLinkify from '../../shared/BugLinkify';
import { getRepoUrl } from '../../helpers/url';

const statusInfoMap = {
  open: {
    icon: 'fa-circle-o',
    color: 'tree-open',
    btnClass: 'btn-view-nav',
  },
  'approval required': {
    icon: 'fa-lock',
    color: 'tree-approval',
    btnClass: 'btn-view-nav',
  },
  closed: {
    icon: 'fa-times-circle',
    color: 'tree-closed',
    btnClass: 'btn-view-nav-closed',
  },
  unsupported: {
    icon: 'fa-question',
    color: 'tree-unavailable',
    btnClass: 'btn-view-nav',
  },
  'not retrieved yet': {
    icon: 'fa-spinner',
    pulseIcon: 'fa-pulse',
    color: 'tree-unavailable',
    btnClass: 'btn-view-nav',
  },
  error: {
    icon: 'fa-question',
    color: 'tree-unavailable',
    btnClass: 'btn-view-nav',
  },
};

export default class WatchedRepo extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      status: 'not retrieved yet',
      reason: '',
      messageOfTheDay: '',
      statusInfo: {
        icon: 'fa-spinner',
        pulseIcon: 'fa-pulse',
        color: 'tree-unavailable',
        btnClass: 'btn-view-nav',
      },
      hasBoundaryError: false,
      boundaryError: '',
    };
  }

  componentDidMount() {
    this.updateTreeStatus = this.updateTreeStatus.bind(this);

    this.updateTreeStatus();
    // update the TreeStatus every 2 minutes
    this.treeStatusIntervalId = setInterval(
      this.updateTreeStatus,
      2 * 60 * 1000,
    );
  }

  componentWillUnmount() {
    clearInterval(this.treeStatusIntervalId);
  }

  componentDidCatch(error) {
    this.setState({
      hasBoundaryError: true,
      boundaryError: error,
    });
  }

  updateTreeStatus() {
    const { repo, repoName, setCurrentRepoTreeStatus } = this.props;
    const watchedRepoName = repo.name;

    TreeStatusModel.get(watchedRepoName).then(data => {
      const treeStatus = data.result;

      if (watchedRepoName === repoName) {
        setCurrentRepoTreeStatus(treeStatus.status);
      }

      this.setState({
        status: treeStatus.status,
        reason: treeStatus.reason,
        messageOfTheDay: treeStatus.message_of_the_day,
        statusInfo: statusInfoMap[treeStatus.status],
      });
    });
  }

  render() {
    const { repoName, unwatchRepo, repo } = this.props;
    const {
      status,
      messageOfTheDay,
      reason,
      statusInfo,
      hasBoundaryError,
      boundaryError,
    } = this.state;
    const watchedRepo = repo.name;
    const activeClass = watchedRepo === repoName ? 'active' : '';
    const { btnClass, icon, color } = statusInfo;
    const pulseIcon = statusInfo.pulseIcon || '';
    const treeStatusName = TreeStatusModel.getTreeStatusName(watchedRepo);
    const changeRepoUrl = getRepoUrl(watchedRepo);

    if (hasBoundaryError) {
      return (
        <span
          className="btn-view-nav pl-1 pr-1 border-right"
          title={boundaryError.toString()}
        >
          Error getting {watchedRepo} info
        </span>
      );
    }
    return (
      <span className="btn-group">
        <a
          href={changeRepoUrl}
          className={`watched-repo-main-btn btn btn-sm ${btnClass} ${activeClass}`}
          type="button"
          title={status}
        >
          <i className={`fa ${icon} ${pulseIcon} ${color}`} /> {watchedRepo}
        </a>
        <button
          className={`watched-repo-info-btn btn btn-sm btn-view-nav ${activeClass}`}
          type="button"
          title={`${watchedRepo} info`}
          aria-label={`${watchedRepo} info`}
          data-toggle="dropdown"
        >
          <span className="fa fa-info-circle" />
        </button>
        {watchedRepo !== repoName && (
          <button
            className={`watched-repo-unwatch-btn btn btn-sm btn-view-nav ${activeClass}`}<commit_msg>Remove redundant error boundary in WatchedRepo (#4347)<commit_after>import React from 'react';
import PropTypes from 'prop-types';

import TreeStatusModel from '../../models/treeStatus';
import BugLinkify from '../../shared/BugLinkify';
import { getRepoUrl } from '../../helpers/url';

const statusInfoMap = {
  open: {
    icon: 'fa-circle-o',
    color: 'tree-open',
    btnClass: 'btn-view-nav',
  },
  'approval required': {
    icon: 'fa-lock',
    color: 'tree-approval',
    btnClass: 'btn-view-nav',
  },
  closed: {
    icon: 'fa-times-circle',
    color: 'tree-closed',
    btnClass: 'btn-view-nav-closed',
  },
  unsupported: {
    icon: 'fa-question',
    color: 'tree-unavailable',
    btnClass: 'btn-view-nav',
  },
  'not retrieved yet': {
    icon: 'fa-spinner',
    pulseIcon: 'fa-pulse',
    color: 'tree-unavailable',
    btnClass: 'btn-view-nav',
  },
  error: {
    icon: 'fa-question',
    color: 'tree-unavailable',
    btnClass: 'btn-view-nav',
  },
};

export default class WatchedRepo extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      status: 'not retrieved yet',
      reason: '',
      messageOfTheDay: '',
      statusInfo: {
        icon: 'fa-spinner',
        pulseIcon: 'fa-pulse',
        color: 'tree-unavailable',
        btnClass: 'btn-view-nav',
      },
    };
  }

  componentDidMount() {
    this.updateTreeStatus = this.updateTreeStatus.bind(this);

    this.updateTreeStatus();
    // update the TreeStatus every 2 minutes
    this.treeStatusIntervalId = setInterval(
      this.updateTreeStatus,
      2 * 60 * 1000,
    );
  }

  componentWillUnmount() {
    clearInterval(this.treeStatusIntervalId);
  }

  updateTreeStatus() {
    const { repo, repoName, setCurrentRepoTreeStatus } = this.props;
    const watchedRepoName = repo.name;

    TreeStatusModel.get(watchedRepoName).then(data => {
      const treeStatus = data.result;

      if (watchedRepoName === repoName) {
        setCurrentRepoTreeStatus(treeStatus.status);
      }

      this.setState({
        status: treeStatus.status,
        reason: treeStatus.reason,
        messageOfTheDay: treeStatus.message_of_the_day,
        statusInfo: statusInfoMap[treeStatus.status],
      });
    });
  }

  render() {
    const { repoName, unwatchRepo, repo } = this.props;
    const { status, messageOfTheDay, reason, statusInfo } = this.state;
    const watchedRepo = repo.name;
    const activeClass = watchedRepo === repoName ? 'active' : '';
    const { btnClass, icon, color } = statusInfo;
    const pulseIcon = statusInfo.pulseIcon || '';
    const treeStatusName = TreeStatusModel.getTreeStatusName(watchedRepo);
    const changeRepoUrl = getRepoUrl(watchedRepo);

    return (
      <span className="btn-group">
        <a
          href={changeRepoUrl}
          className={`watched-repo-main-btn btn btn-sm ${btnClass} ${activeClass}`}
          type="button"
          title={status}
        >
          <i className={`fa ${icon} ${pulseIcon} ${color}`} /> {watchedRepo}
        </a>
        <button
          className={`watched-repo-info-btn btn btn-sm btn-view-nav ${activeClass}`}
          type="button"
          title={`${watchedRepo} info`}
          aria-label={`${watchedRepo} info`}
          data-toggle="dropdown"
        >
          <span className="fa fa-info-circle" />
        </button>
        {watchedRepo !== repoName && (
          <button
            className={`watched-repo-unwatch-btn btn btn-sm btn-view-nav ${activeClass}`}
{'fraction_non_alphanumeric': 0.14253181513730742, 'fraction_numerical': 0.0029470864032150033, 'mean_word_length': 2.531693472090823, 'pattern_counts': {'":': 0, '<': 21, '<?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': '2874292', 'n_tokens_mistral': 2351, 'n_tokens_neox': 2355, 'n_words': 458}