<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import UserUtils from '../../utils/user_utils.js';

const ArticleViewerLegend = ({ article, users, colors, status }) => {
  let userLinks;
  if (users) {
    userLinks = users.map((user, i) => {
      const userLink = UserUtils.userTalkUrl(user.name, article.language, article.project);
      return (
        <div key={`legend-${user.name}`} className={`user-legend ${colors[i]}`}>
          <a href={userLink} target="_blank">{user.name}</a>
        </div>
      );
    });
  } else {
    userLinks = <div className="user-legend authorship-loading"> &nbsp; &nbsp; </div>;
  }

  let usersStatus;
  if (status === 'loading') {
    usersStatus = (
      <div>
        <div className="user-legend authorship-loading"> &nbsp; &nbsp; </div>
        <div className="user-legend authorship-status">{I18n.t('users.loading_authorship_data')}</div>
        <div className="user-legend authorship-loading"> &nbsp; &nbsp; </div>
      </div>
    );
  } else if (status === 'failed') {
    usersStatus = <div className="user-legend authorship-status-failed">{I18n.t('users.authorship_data_not_fetched')}</div>;
  }

  return (
    <div className="user-legend-wrap">
      <div className="user-legend">{I18n.t('users.edits_by')} </div>
      {userLinks}
      {usersStatus}
    </div>
  );
};

ArticleViewerLegend.propTypes = {
  article: PropTypes.object,
  users: PropTypes.array,
  colors: PropTypes.array,
  status: PropTypes.string
};

export default ArticleViewerLegend;<commit_msg>Add real name on mouseover to ArticleViewerLegend<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { connect } from "react-redux";

import UserUtils from '../../utils/user_utils.js';

const ArticleViewerLegend = ({ article, users, colors, status, allUsers }) => {
  let userLinks;
  if (users) {
    userLinks = users.map((user, i) => {
      const userLink = UserUtils.userTalkUrl(user.name, article.language, article.project);
      const fullUserRecord = allUsers.find(_user => _user.username === user.name);
      const realName = fullUserRecord && fullUserRecord.real_name;
      return (
        <div key={`legend-${user.name}`} className={`user-legend ${colors[i]}`}>
          <a href={userLink} title={realName} target="_blank">{user.name}</a>
        </div>
      );
    });
  } else {
    userLinks = <div className="user-legend authorship-loading"> &nbsp; &nbsp; </div>;
  }

  let usersStatus;
  if (status === 'loading') {
    usersStatus = (
      <div>
        <div className="user-legend authorship-loading"> &nbsp; &nbsp; </div>
        <div className="user-legend authorship-status">{I18n.t('users.loading_authorship_data')}</div>
        <div className="user-legend authorship-loading"> &nbsp; &nbsp; </div>
      </div>
    );
  } else if (status === 'failed') {
    usersStatus = <div className="user-legend authorship-status-failed">{I18n.t('users.authorship_data_not_fetched')}</div>;
  }

  return (
    <div className="user-legend-wrap">
      <div className="user-legend">{I18n.t('users.edits_by')} </div>
      {userLinks}
      {usersStatus}
    </div>
  );
};

ArticleViewerLegend.propTypes = {
  article: PropTypes.object,
  users: PropTypes.array,
  colors: PropTypes.array,
  status: PropTypes.string
};

const mapStateToProps = state => ({
  allUsers: state.users.users
});

export default connect(mapStateToProps)(ArticleViewerLegend);
{'fraction_non_alphanumeric': 0.16714864083285136, 'fraction_numerical': 0.003470213996529786, 'mean_word_length': 3.581456953642384, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 49, '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': '2014956', 'n_tokens_mistral': 1135, 'n_tokens_neox': 1116, 'n_words': 223}