<commit_before>import React, { useState } from 'react';
import { Card, CardHeader, CardText } from 'material-ui/Card';
import ConnectionPoint from '../ConnectionPoint';
import FontIcon from 'material-ui/FontIcon';
import { connect } from 'react-redux';
import UnlockRateDisplay from '../UnlockRateDisplay';
import { elementTypes } from '../../constants';
import NodeMenu from '../NodeMenu';

const styles = {
  connectionPoint: {
    position: 'absolute',
    right: '2.5%',
  },
  content: {
    alignItems: 'center',
    display: 'flex',
    justifyContent: 'center',
    width: '100%',
  },
  contentText: {
    flexGrow: 1,
    textAlign: 'center',
  },
  header: {
    alignItems: 'center-top',
    display: 'flex',
    justifyContent: 'center',
    padding: 0,
    width: '100%',
  },
  headerText: {
    padding: 0,
    position: 'absolute',
  },
  icon: {
    fontSize: 12,
    padding: '0px',
  },
  lockIcon: {
    marginLeft: 4,
    opacity: 1.0,
  },
  unlockLevel: {
    cursor: 'pointer',
    fontSize: 12,
    left: 0,
    position: 'absolute',
    top: 0,
  },
  wrapper: {
    border: '1px solid black',
    margin: 20,
    padding: 4,
    position: 'relative',
    width: 180,
  },
};

const icons = {
  achievement: 'fa fa-trophy',
  assessment: 'fa fa-plane',
  lock: 'fa fa-lock',
  material: 'fa fa-folder',
  survey: 'fa fa-pie-chart',
  video: 'fa fa-video-camera',
}

const Node = (props) => {
  const {
    canModify,
    getNodeConnectionPointId,
    node,
    selectedElement,
  } = props;

  const onConnectionPointClick = (event) => {
    event.stopPropagation();
    setIsNodeMenuDisplayed(true);
  };

  const [isNodeMenuDisplayed, setIsNodeMenuDisplayed] = useState(false);

  return (
    <>
      <Card
        id={node.id}
        style={{
          ...styles.wrapper,
          opacity: `${!canModify && !node.unlocked ? 0.2 : 1.0}`,
          zIndex: isNodeMenuDisplayed ? 999 : node.depth + 2
        }}
      >
        <CardHeader
          style={styles.header}
          textStyle={styles.headerText}
        >
          {
            node.unlock_level > 0 &&
            <>
              <div style={styles.unlockLevel}>
                Level {node.unlock_level}
              </div>
            </>
          }
          <FontIcon
            className={icons[node.course_material_type]}
            style={styles.icon}
          />
          {
            !canModify && !node.unlocked &&
            <>
              <FontIcon
                className={icons.lock}
                style={{...styles.icon, ...styles.lockIcon}}
              />
            </>
          }
        </CardHeader>
        <div style={styles.content}>
          <CardText style={styles.contentText}>
            <div>
              <a target='_blank' href={`${node.content_url}`}>
              {node.title}
              </a>
            </div>
            {
              canModify &&
              <UnlockRateDisplay
                nodeId={node.id}
                unlockRate={node.unlock_rate}
                width={0.6 * styles.wrapper.width}
              />
            }
          </CardText>
          <div style={styles.connectionPoint}>
            <ConnectionPoint
              id={getNodeConnectionPointId(node.id)}
              isActive={canModify}
              onClick={(event) => onConnectionPointClick(event, node.id)}
            />
            {
              isNodeMenuDisplayed &&
              <NodeMenu
                closeMenuCallback={() => setIsNodeMenuDisplayed(false)}
                parentNode={node}
              />
            }
          </div>
        </div>
      </Card>
    </>
  );
};

const mapStateToProps = (state) => ({
  canModify: state.learningMap.canModify,
  selectedElement: state.learningMap.selectedElement,
});

export default connect(mapStateToProps)(Node);
<commit_msg>feat (learning map): add extra div with white background behind node so that arrows do not overlap with translucent nodes in the student view<commit_after>import React, { useState } from 'react';
import { Card, CardHeader, CardText } from 'material-ui/Card';
import ConnectionPoint from '../ConnectionPoint';
import FontIcon from 'material-ui/FontIcon';
import { connect } from 'react-redux';
import UnlockRateDisplay from '../UnlockRateDisplay';
import NodeMenu from '../NodeMenu';

const styles = {
  connectionPoint: {
    position: 'absolute',
    right: '2.5%',
  },
  content: {
    alignItems: 'center',
    display: 'flex',
    justifyContent: 'center',
    width: '100%',
  },
  contentText: {
    flexGrow: 1,
    textAlign: 'center',
  },
  header: {
    alignItems: 'center-top',
    display: 'flex',
    justifyContent: 'center',
    padding: 0,
    width: '100%',
  },
  headerText: {
    padding: 0,
    position: 'absolute',
  },
  icon: {
    fontSize: 12,
    padding: '0px',
  },
  lockIcon: {
    marginLeft: 4,
    opacity: 1.0,
  },
  node: {
    border: '1px solid black',
    padding: 4,
    position: 'relative',
    width: 180,
  },
  unlockLevel: {
    cursor: 'pointer',
    fontSize: 12,
    left: 0,
    position: 'absolute',
    top: 0,
  },
  wrapper: {
    backgroundColor: 'white',
    width: 180,
    margin: 20,
  },
};

const icons = {
  achievement: 'fa fa-trophy',
  assessment: 'fa fa-plane',
  lock: 'fa fa-lock',
  material: 'fa fa-folder',
  survey: 'fa fa-pie-chart',
  video: 'fa fa-video-camera',
}

const Node = (props) => {
  const {
    canModify,
    getNodeConnectionPointId,
    node,
  } = props;

  const onConnectionPointClick = (event) => {
    event.stopPropagation();
    setIsNodeMenuDisplayed(true);
  };

  const [isNodeMenuDisplayed, setIsNodeMenuDisplayed] = useState(false);
  const zIndex = isNodeMenuDisplayed ? 999 : node.depth + 2;

  return (
    <>
      <div style={{...styles.wrapper, zIndex: zIndex}}>
        <Card
          id={node.id}
          style={{
            ...styles.node,
            opacity: `${!canModify && !node.unlocked ? 0.2 : 1.0}`,
            zIndex: zIndex
          }}
        >
          <CardHeader
            style={styles.header}
            textStyle={styles.headerText}
          >
            {
              node.unlock_level > 0 &&
              <>
                <div style={styles.unlockLevel}>
                  Level {node.unlock_level}
                </div>
              </>
            }
            <FontIcon
              className={icons[node.course_material_type]}
              style={styles.icon}
            />
            {
              !canModify && !node.unlocked &&
              <>
                <FontIcon
                  className={icons.lock}
                  style={{...styles.icon, ...styles.lockIcon}}
                />
              </>
            }
          </CardHeader>
          <div style={styles.content}>
            <CardText style={styles.contentText}>
              <div>
                <a target='_blank' href={`${node.content_url}`}>
                {node.title}
                </a>
              </div>
              {
                canModify &&
                <UnlockRateDisplay
                  nodeId={node.id}
                  unlockRate={node.unlock_rate}
                  width={0.6 * styles.wrapper.width}
                />
              }
            </CardText>
            <div style={styles.connectionPoint}>
              <ConnectionPoint
                id={getNodeConnectionPointId(node.id)}
                isActive={canModify}
                onClick={(event) => onConnectionPointClick(event, node.id)}
              />
              {
                isNodeMenuDisplayed &&
                <NodeMenu
                  closeMenuCallback={() => setIsNodeMenuDisplayed(false)}
                  parentNode={node}
                />
              }
            </div>
          </div>
        </Card>
      </div>
    </>
  );
};

const mapStateToProps = (state) => ({
  canModify: state.learningMap.canModify,
  selectedElement: state.learningMap.selectedElement,
});

export default connect(mapStateToProps)(Node);

{'fraction_non_alphanumeric': 0.13653870045968444, 'fraction_numerical': 0.01006336190831159, 'mean_word_length': 1.699530516431925, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 71, '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': '2496142', 'n_tokens_mistral': 2439, 'n_tokens_neox': 2364, 'n_words': 477}