<commit_before>import React from 'react';
import ReactDOM from 'react-dom';

// Import React libraries
import Select from 'react-select';
import ReactClickOut from 'react-onclickout';
import scrollIntoView from 'scroll-into-view';

// Import React components
import Button from '../common/Button.jsx';
import IconButton from '../common/IconButton.jsx';
import ModalContainer from '../common/ModalContainer.jsx';
import Tab from './Tab.jsx';
import AcadYrSectionContainer from './AcadYrSectionContainer.js';
import AddNewPlannerContainer from './AddNewPlannerContainer.js';

// Import server-side methods
import { createPlanner,
         removePlanner,
         duplicatePlanner,
         setPlannerName } from '../../../api/crud-controller/planner/methods.js';

 // Import common constants and utilities
 import { ENTER_CHAR_KEY_CODE,
          MAX_STUDY_PLAN_NAME_LENGTH,
          MIN_STUDY_PLAN_NAME_LENGTH } from '../common/Constants.js';
 import { isDefinedObj,
          getFirstNChars } from '../../../utils/util.js';


/**
 * React Component for a TabbedContainer that holds the user's study plan.
 * Every study plan is displayed in a panel within the TabbedContainer.
 * Different study plans may be viewed by selecting its corresponding Tab.
 */
export default class TabbedContainer extends React.Component {
  constructor() {
    super();
    this.state = {
      newPlannerDialog: null,
      tabSelectedIndex: 0,
      isAddingNewPlan: false,
      isModalVisible: false,
      isEditingPlanName: false,
      planNameToEdit: false
    }
  }

  /**
   * Display Add New Planner Dialog only when component is completely mounted
   */
  componentDidMount(){
    this.setState({
      newPlannerDialog:
        <AddNewPlannerContainer
          handleAddBlankTemplate={this.handleAddBlankTemplate.bind(this)}
          handleAddedTemplate={this.handleAddTemplate.bind(this)} />
    });
  }

  //======================================================
  // EVENT HANDLERS WITHIN THIS TAB
  //======================================================
  /**
   * Handler for when user clicks on a tab
   *
   * @param {[int]} index    Index of the tab the user clicked on. From the
   *                         left onscreen, the indices start from 0.
   */
  handleClickTab(index) {
    this.props.handleSelectTab(index);
    this.setState({tabSelectedIndex: index});
  }

  /**
   * Handler for when user is entering a new study plan's name
   *
   * @param {[Object]} event    Event object of this HTML object
   */
  handleEnterStudyPlanName(event) {
    if (isDefinedObj(event)) {
      let userInputStudyPlanName = event.target.value;

      if (event.charCode == ENTER_CHAR_KEY_CODE) { // If pressed ENTER
        if (this.state.isAddingNewPlan) {
          this.setState({ isAddingNewPlan: false });
          createPlanner(userInputStudyPlanName, ["focusArea"]);
          this.setState({tabSelectedIndex:this.props.plannerIDs.length});
        }
      }
    }
  }

  /**
   * Handler for when user clicks outside of the input field when adding a
   * study plan and entering a new study plan's name
   *
   * @param {[Object]} event    Event object of this HTML object
   */
  handleCancelAddStudyPlan(event) {
    this.setState({ isAddingNewPlan: false });
    // If the user already entered a name, add study plan for convenience
    if (isDefinedObj(event)) {
      let userInputStudyPlanName = event.target.value;
      if (userInputStudyPlanName) {
        createPlanner(userInputStudyPlanName, ["focusArea"]);
        this.setState({tabSelectedIndex:this.props.plannerIDs.length});
      }
    }
  }

  /**
   * Handler for add study plan button on the right hand side of all tabs
   */
  handleAddStudyPlanClick() {
    this.setState({ isModalVisible : true });
  }

  /**
   * Handler for hiding study plan modal
   */
  handleCloseAddPlanModal() {
    this.setState({ isModalVisible : false });
  }

  /**
   * Handles event where user already selected a study
   * plan template that isn't a blank one
   */
  handleAddTemplate() {
    this.setState({
      isModalVisible : false,
      tabSelectedIndex:this.props.plannerIDs.length
    });
  }

  /**
   * Handles event where user selected a blank study
   * plan template
   */
  handleAddBlankTemplate(){
    this.setState({
      isModalVisible : false,
      isAddingNewPlan : true
    });
  }

  /**
   * Handler for deleting study plan.
   *
   * @param {[int]} index    Index of the study plan to delete represented by
   *                         the tab's index from the left. From the
   *                         left onscreen, the indices start from 0.
   */
  handleDeleteStudyPlanClick(index) {
    let studyPlanIDToDelete = this.props.plannerIDs[index];
    removePlanner(studyPlanIDToDelete);

    // if deleting last planner, auto select previous planner
    if(index == this.props.plannerIDs.length - 1){<commit_msg>FIXED bug where on addNewTab, plannerID not updated<commit_after>import React from 'react';
import ReactDOM from 'react-dom';

// Import React libraries
import Select from 'react-select';
import ReactClickOut from 'react-onclickout';
import scrollIntoView from 'scroll-into-view';

// Import React components
import Button from '../common/Button.jsx';
import IconButton from '../common/IconButton.jsx';
import ModalContainer from '../common/ModalContainer.jsx';
import Tab from './Tab.jsx';
import AcadYrSectionContainer from './AcadYrSectionContainer.js';
import AddNewPlannerContainer from './AddNewPlannerContainer.js';

// Import server-side methods
import { createPlanner,
         removePlanner,
         duplicatePlanner,
         setPlannerName } from '../../../api/crud-controller/planner/methods.js';

 // Import common constants and utilities
 import { ENTER_CHAR_KEY_CODE,
          MAX_STUDY_PLAN_NAME_LENGTH,
          MIN_STUDY_PLAN_NAME_LENGTH } from '../common/Constants.js';
 import { isDefinedObj,
          getFirstNChars } from '../../../utils/util.js';


/**
 * React Component for a TabbedContainer that holds the user's study plan.
 * Every study plan is displayed in a panel within the TabbedContainer.
 * Different study plans may be viewed by selecting its corresponding Tab.
 */
export default class TabbedContainer extends React.Component {
  constructor() {
    super();
    this.state = {
      newPlannerDialog: null,
      tabSelectedIndex: 0,
      isAddingNewPlan: false,
      isModalVisible: false,
      isEditingPlanName: false,
      planNameToEdit: false
    }
  }

  /**
   * Display Add New Planner Dialog only when component is completely mounted
   */
  componentDidMount(){
    this.setState({
      newPlannerDialog:
        <AddNewPlannerContainer
          handleAddBlankTemplate={this.handleAddBlankTemplate.bind(this)}
          handleAddedTemplate={this.handleAddTemplate.bind(this)} />
    });
  }

  //======================================================
  // EVENT HANDLERS WITHIN THIS TAB
  //======================================================
  /**
   * Handler for when user clicks on a tab
   *
   * @param {[int]} index    Index of the tab the user clicked on. From the
   *                         left onscreen, the indices start from 0.
   */
  handleClickTab(index) {
    this.props.handleSelectTab(index);
    this.setState({tabSelectedIndex: index});
  }

  /**
   * Handler for when user is entering a new study plan's name
   *
   * @param {[Object]} event    Event object of this HTML object
   */
  handleEnterStudyPlanName(event) {
    if (isDefinedObj(event)) {
      let userInputStudyPlanName = event.target.value;

      if (event.charCode == ENTER_CHAR_KEY_CODE) { // If pressed ENTER
        if (this.state.isAddingNewPlan) {
          this.setState({ isAddingNewPlan: false });
          createPlanner(userInputStudyPlanName, ["focusArea"]);
          this.setState({tabSelectedIndex:this.props.plannerIDs.length});
        }
      }
    }
  }

  /**
   * Handler for when user clicks outside of the input field when adding a
   * study plan and entering a new study plan's name
   *
   * @param {[Object]} event    Event object of this HTML object
   */
  handleCancelAddStudyPlan(event) {
    this.setState({ isAddingNewPlan: false });
    // If the user already entered a name, add study plan for convenience
    if (isDefinedObj(event)) {
      let userInputStudyPlanName = event.target.value;
      if (userInputStudyPlanName) {
        createPlanner(userInputStudyPlanName, ["focusArea"]);
        this.setState({tabSelectedIndex:this.props.plannerIDs.length});
      }
    }
  }

  /**
   * Handler for add study plan button on the right hand side of all tabs
   */
  handleAddStudyPlanClick() {
    this.setState({ isModalVisible : true });
  }

  /**
   * Handler for hiding study plan modal
   */
  handleCloseAddPlanModal() {
    this.setState({ isModalVisible : false });
  }

  /**
   * Handles event where user already selected a study
   * plan template that isn't a blank one
   */
  handleAddTemplate() {
    let indexOfStudyPlanTabAdded = this.props.plannerIDs.length;
    this.props.handleSelectTab(indexOfStudyPlanTabAdded);

    this.setState({
      isModalVisible : false,
      tabSelectedIndex:this.props.plannerIDs.length
    });
  }

  /**
   * Handles event where user selected a blank study
   * plan template
   */
  handleAddBlankTemplate(){
    let indexOfStudyPlanTabAdded = this.props.plannerIDs.length;
    this.props.handleSelectTab(indexOfStudyPlanTabAdded);

    this.setState({
      isModalVisible : false,
      isAddingNewPlan : true
    });
  }

  /**
   * Handler for deleting study plan.
   *
   * @param {[int]} index    Index of the study plan to delete represented by
   *                         the tab's index from the left. From the
   *                         left onscreen, the indices start from 0.
   */
  handleDeleteStudyPlanClick(index) {
    let studyPlanIDToDelete = this.props.plannerIDs[index];
    removePlanner(studyPlanIDToDelete);

    // if deleting last planner, auto select previous planner
    if(index == this.props.plannerIDs.length - 1){
{'fraction_non_alphanumeric': 0.11943399960419553, 'fraction_numerical': 0.0007916089451810805, 'mean_word_length': 2.9388152766952453, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '367367', 'n_tokens_mistral': 2906, 'n_tokens_neox': 2801, 'n_words': 800}