<commit_before>import React from 'react'
import {some} from 'lodash'
import List from '../List'
import Sidebar from '../../../styled/Sidebar'
import Arrow from '../../../styled/Arrow'
import ContextNavLink from '../../../styled/ContextNavLink'
import {
  SEARCH_LIMIT,
  matchesQuery,
  isContextSelected,
  isScenarioSelected,
  areContextChildrenSelected
} from '../../_lib/utils'

let PropTypes
try {
  PropTypes = require('prop-types')
} catch (e) {
  // Ignore optional peer dependency
}

/**
 * Component which represents context node of the node tree in sidebar.
 * @extends React.Component
 * @property {ContextObject} props.node
 * @property {Object} props.selectedRoute - name of selected route, and if available, selected scenario and context
 * @property {String} [props.searchQuery]
 */
class Context extends React.Component {
  _hasFailingChildren () {
    return this.props.node.children.find(({hasDiff}) => hasDiff)
  }

  _shouldExpand () {
    return window.location.pathname.match(`/contexts/${this.props.node.name}`) ||
      this._hasFailingChildren() || (this._applyFilter() && this._searchMatchChildren())
  }

  _applyFilter () {
    return this.props.searchQuery.length >= SEARCH_LIMIT
  }

  _matchFilter () {
    return matchesQuery(this.props.searchQuery, this.props.node.name)
  }

  _searchMatchChildren () {
    return some(this.props.node.children, child => (
      matchesQuery(this.props.searchQuery, child.name)
    ))
  }

  _renderIcon () {
    return this._shouldExpand() ? <Arrow.Down /> : <Arrow.Right />
  }

  render () {
    const {selectedRoute} = this.props
    const {name, children} = this.props.node

    // If context's name matches filter, render all children.
    // Otherwise, filter them by query or selected
    const filteredChildren = this._matchFilter()
      ? children
      : children.filter(scenario => {
        return matchesQuery(this.props.searchQuery, scenario.name) ||
          isScenarioSelected(selectedRoute, name, scenario.name)
      })

    const hasSelectedChildren = areContextChildrenSelected(selectedRoute, name)
    const active = isContextSelected(selectedRoute, name)

    return (hasSelectedChildren || filteredChildren.length > 0) &&
      <Sidebar.ListItem key={name}>
        <ContextNavLink
          name='context'
          params={{context: name}}
          active={active}
        >
          {this._renderIcon()}
          <span ref={ref =>
            ref && active && ref.scrollIntoViewIfNeeded && ref.scrollIntoViewIfNeeded()
          }>
            {name}
          </span>
        </ContextNavLink>
        {this._shouldExpand() && <List nodes={filteredChildren} selectedRoute={selectedRoute} child />}
      </Sidebar.ListItem>
  }
}

if (PropTypes) {
  Context.propTypes = {
    node: PropTypes.object.isRequired,
    searchQuery: PropTypes.string,
    selectedRoute: PropTypes.object.isRequired
  }
}

export default Context<commit_msg>Fix context incorrectly not expanding bug (#22)<commit_after>import React from 'react'
import {some} from 'lodash'
import List from '../List'
import Sidebar from '../../../styled/Sidebar'
import Arrow from '../../../styled/Arrow'
import ContextNavLink from '../../../styled/ContextNavLink'
import {
  SEARCH_LIMIT,
  matchesQuery,
  isContextSelected,
  isScenarioSelected,
  areContextChildrenSelected
} from '../../_lib/utils'

let PropTypes
try {
  PropTypes = require('prop-types')
} catch (e) {
  // Ignore optional peer dependency
}

/**
 * Component which represents context node of the node tree in sidebar.
 * @extends React.Component
 * @property {ContextObject} props.node
 * @property {Object} props.selectedRoute - name of selected route, and if available, selected scenario and context
 * @property {String} [props.searchQuery]
 */
class Context extends React.Component {
  _hasFailingChildren () {
    return this.props.node.children.find(({hasDiff}) => hasDiff)
  }

  _shouldExpand () {
    return this._hasFailingChildren() || (this._applyFilter() && this._searchMatchChildren())
  }

  _applyFilter () {
    return this.props.searchQuery.length >= SEARCH_LIMIT
  }

  _matchFilter () {
    return matchesQuery(this.props.searchQuery, this.props.node.name)
  }

  _searchMatchChildren () {
    return some(this.props.node.children, child => (
      matchesQuery(this.props.searchQuery, child.name)
    ))
  }

  _renderIcon () {
    return this._shouldExpand() ? <Arrow.Down /> : <Arrow.Right />
  }

  render () {
    const {selectedRoute} = this.props
    const {name, children} = this.props.node

    // If context's name matches filter, render all children.
    // Otherwise, filter them by query or selected
    const filteredChildren = this._matchFilter()
      ? children
      : children.filter(scenario => {
        return matchesQuery(this.props.searchQuery, scenario.name) ||
          isScenarioSelected(selectedRoute, name, scenario.name)
      })

    const hasSelectedChildren = areContextChildrenSelected(selectedRoute, name)
    const active = isContextSelected(selectedRoute, name)

    return (hasSelectedChildren || filteredChildren.length > 0) &&
      <Sidebar.ListItem key={name}>
        <ContextNavLink
          name='context'
          params={{context: name}}
          active={active}
        >
          {this._renderIcon()}
          <span ref={ref =>
            ref && active && ref.scrollIntoViewIfNeeded && ref.scrollIntoViewIfNeeded()
          }>
            {name}
          </span>
        </ContextNavLink>
        {(active || hasSelectedChildren || this._shouldExpand()) && <List nodes={filteredChildren} selectedRoute={selectedRoute} child />}
      </Sidebar.ListItem>
  }
}

if (PropTypes) {
  Context.propTypes = {
    node: PropTypes.object.isRequired,
    searchQuery: PropTypes.string,
    selectedRoute: PropTypes.object.isRequired
  }
}

export default Context
{'fraction_non_alphanumeric': 0.126193724420191, 'fraction_numerical': 0.0006821282401091405, 'mean_word_length': 3.150743099787686, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 33, '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': '3859949', 'n_tokens_mistral': 1668, 'n_tokens_neox': 1657, 'n_words': 386}