<commit_before>import _ from 'underscore'
import React from 'react';
import Autosuggest from 'react-autosuggest';

import { sendQuery } from '../../../api/searcher-controller/controller.js'

/**
 * React Component that implements the module search bar which
 * handles addition of modules into a student's semester.
 *
 * * For reference, a module object is formatted like this:
 * { "_id" : "Wt4PPojMhFPeiKTxZ",
 *   "moduleCode" : "CS1010",
 *   "moduleName" : "Programming Methodology",
 *   "moduleDescription" : "Lorem ipsum", "modulePrerequisite" : "Lorem ipsum",
 *   "moduleCorequisite" : "Lorem ipsum", "modulePreclusion" : "Lorem ipsum",
 *   "moduleMC" : 4, "termOffered" : { "Sem1" : "Sem 1", "Sem2" : "Sem 2" } }
 */
export default class ModuleSearchBar extends React.Component {
  constructor() {
    super();

    this.state = {
      userInput: "",
      suggestions: []
    }
  }

  //=============================================
  // Pre-processing rendering styles
  //=============================================
  /**
   * Renders the suggestions container onto the default autosuggest box's style
   * @param  {[array of objs]} children    List of suggestions Autosuggest will
   *                                       pass in
   * @param  {[object]} props    Style props Autosuggest will pass in
   * @return {[object]}          Custom HTML element for the design of a
   *                             suggestion container
   */
  renderSuggestionsContainer({children, ...props}) {
    let style = {
      position:'absolute',
      zIndex:'3',
      overflowY: 'auto',
      height: '8em',
      'background': '#f6c18a',
      'opacity': '0.75'
    }
    return (
      <div {...props}>
        <ul style={style}>
          {children}
        </ul>
      </div>
    );
  }

  /**
   * Renders the suggestion onto the autosuggest input box.
   *
   * @param  {[object]} suggestion    Module object representing a suggestion
   * @return {[object]}    Custom HTML element for the design of each suggestion
   */
  renderSuggestion(suggestion) {
    let moduleCode = suggestion.moduleCode;
    let nonHighlightedBG = "transparent";
    let highlightedBG = "#ec7513";
    return(
      <div className="typeahead-item" style={{width: '9em'}}
           ref={(htmlElem) => {
                  if (htmlElem) { // Ensure it's not null
                    if (this.state.userInput === moduleCode) {
                      htmlElem.style.backgroundColor = highlightedBG;
                    } else {
                      htmlElem.style.backgroundColor = nonHighlightedBG;
                    }
                  }
               }}>
        {moduleCode}
      </div>
    );
  }

  /**
   * Populates the autocomplete input box when a suggestion has been
   * selected. E.g. If a student hovers over "CS1010" in the
   * suggestion box, this component will populate the input box
   * with the returned value.
   *
   * @param  {[object]} suggestion    Module object
   * @return {[string]}    String representation of the input element to be
   *                       populated into the autosuggest input box.
   */
  getSuggestionValue(suggestion) {
    return suggestion.moduleCode;
  }

  //=============================================
  // Event Handlers
  //=============================================
  /**
   * Event where the list of suggestions displayed needs to be re-computed,
   * we compute how suggestions are displayed as a list to the user.
   *
   * @param {[string]} value    Value typed in to the search box by user
   */
  onSuggestionsFetchRequested(userInput) {
    let extractedValue = userInput.value;
    let inputValue = extractedValue.trim().toLowerCase(); //string normalization
    const inputLength = extractedValue.length;

    let listOfSuggestions = [];
    if (inputLength !== 0) {
      // Return suggestions from modules database that best match inputValue
      let fetchedListOfModulesFromDB = sendQuery(inputValue);
      // console.log("listOfModulesFromDB: " + _.map(fetchedListOfModulesFromDB, (module) => {return JSON.stringify(module);}));
      listOfSuggestions = fetchedListOfModulesFromDB
    }
    // Update the suggestions to be displayed to user
    this.setState({ suggestions: listOfSuggestions });
  };

  /**
   * Called every time suggestions need to be cleared
   */
  onSuggestionsClearRequested() {
    this.setState({ suggestions: [] });
  };

  /**
   * Updates the input field with what user is typing
   */
  updateInputWithNewValue(event, {newValue}) {
    this.setState({ userInput: newValue });
  }

  /**
   * Adds the user's chosen module to the database
   */
  handleConfirmModule(moduleCode, event) {
    if (event.charCode == 13) { // If pressed ENTER
      console.log("Pressed ENTER for " + moduleCode);
      // Add module to DB
      this.props.handleAddModule(moduleCode);
    }
  }

  render() {
    const userInput = this.state.userInput;<commit_msg>REFACTORED Enter key's global constant<commit_after>import _ from 'underscore'
import React from 'react';
import Autosuggest from 'react-autosuggest';

import { sendQuery } from '../../../api/searcher-controller/controller.js'

const enterKeyCharCode = 13;

/**
 * React Component that implements the module search bar which
 * handles addition of modules into a student's semester.
 *
 * * For reference, a module object is formatted like this:
 * { "_id" : "Wt4PPojMhFPeiKTxZ",
 *   "moduleCode" : "CS1010",
 *   "moduleName" : "Programming Methodology",
 *   "moduleDescription" : "Lorem ipsum", "modulePrerequisite" : "Lorem ipsum",
 *   "moduleCorequisite" : "Lorem ipsum", "modulePreclusion" : "Lorem ipsum",
 *   "moduleMC" : 4, "termOffered" : { "Sem1" : "Sem 1", "Sem2" : "Sem 2" } }
 */
export default class ModuleSearchBar extends React.Component {
  constructor() {
    super();

    this.state = {
      userInput: "",
      suggestions: []
    }
  }

  //=============================================
  // Pre-processing rendering styles
  //=============================================
  /**
   * Renders the suggestions container onto the default autosuggest box's style
   * @param  {[array of objs]} children    List of suggestions Autosuggest will
   *                                       pass in
   * @param  {[object]} props    Style props Autosuggest will pass in
   * @return {[object]}          Custom HTML element for the design of a
   *                             suggestion container
   */
  renderSuggestionsContainer({children, ...props}) {
    let style = {
      position:'absolute',
      zIndex:'3',
      overflowY: 'auto',
      height: '8em',
      'background': '#f6c18a',
      'opacity': '0.75'
    }
    return (
      <div {...props}>
        <ul style={style}>
          {children}
        </ul>
      </div>
    );
  }

  /**
   * Renders the suggestion onto the autosuggest input box.
   *
   * @param  {[object]} suggestion    Module object representing a suggestion
   * @return {[object]}    Custom HTML element for the design of each suggestion
   */
  renderSuggestion(suggestion) {
    let moduleCode = suggestion.moduleCode;
    let nonHighlightedBG = "transparent";
    let highlightedBG = "#ec7513";
    return(
      <div className="typeahead-item" style={{width: '9em'}}
           ref={(htmlElem) => {
                  if (htmlElem) { // Ensure it's not null
                    if (this.state.userInput === moduleCode) {
                      htmlElem.style.backgroundColor = highlightedBG;
                    } else {
                      htmlElem.style.backgroundColor = nonHighlightedBG;
                    }
                  }
               }}>
        {moduleCode}
      </div>
    );
  }

  /**
   * Populates the autocomplete input box when a suggestion has been
   * selected. E.g. If a student hovers over "CS1010" in the
   * suggestion box, this component will populate the input box
   * with the returned value.
   *
   * @param  {[object]} suggestion    Module object
   * @return {[string]}    String representation of the input element to be
   *                       populated into the autosuggest input box.
   */
  getSuggestionValue(suggestion) {
    return suggestion.moduleCode;
  }

  //=============================================
  // Event Handlers
  //=============================================
  /**
   * Event where the list of suggestions displayed needs to be re-computed,
   * we compute how suggestions are displayed as a list to the user.
   *
   * @param {[string]} value    Value typed in to the search box by user
   */
  onSuggestionsFetchRequested(userInput) {
    let extractedValue = userInput.value;
    let inputValue = extractedValue.trim().toLowerCase(); //string normalization
    const inputLength = extractedValue.length;

    let listOfSuggestions = [];
    if (inputLength !== 0) {
      // Return suggestions from modules database that best match inputValue
      let fetchedListOfModulesFromDB = sendQuery(inputValue);
      // console.log("listOfModulesFromDB: " + _.map(fetchedListOfModulesFromDB, (module) => {return JSON.stringify(module);}));
      listOfSuggestions = fetchedListOfModulesFromDB
    }
    // Update the suggestions to be displayed to user
    this.setState({ suggestions: listOfSuggestions });
  };

  /**
   * Called every time suggestions need to be cleared
   */
  onSuggestionsClearRequested() {
    this.setState({ suggestions: [] });
  };

  /**
   * Updates the input field with what user is typing
   */
  updateInputWithNewValue(event, {newValue}) {
    this.setState({ userInput: newValue });
  }

  /**
   * Adds the user's chosen module to the database
   */
  handleConfirmModule(moduleCode, event) {
    if (event.charCode == enterKeyCharCode) { // If pressed ENTER
      console.log("Pressed ENTER for " + moduleCode);
      // Add module to DB
      this.props.handleAddModule(moduleCode);
    }
  }

  render() {
    const userInput = this.state.userInput;
{'fraction_non_alphanumeric': 0.14451910540567647, 'fraction_numerical': 0.006017450606759603, 'mean_word_length': 2.594808940158616, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3866246', 'n_tokens_mistral': 2832, 'n_tokens_neox': 2714, 'n_words': 810}