<commit_before>import React, {PropTypes} from 'react'
import classnames from 'classnames'
import _ from 'lodash'

import {showMeasurements} from 'shared/apis/metaQuery'
import showMeasurementsParser from 'shared/parsing/showMeasurements'
import TagList from './TagList'

const {func, shape, string} = PropTypes

const MeasurementList = React.createClass({
  propTypes: {
    query: shape({
      database: string,
      measurement: string,
    }).isRequired,
    onChooseMeasurement: func.isRequired,
    onChooseTag: func.isRequired,
    onToggleTagAcceptance: func.isRequired,
    onGroupByTag: func.isRequired,
  },

  contextTypes: {
    source: shape({
      links: shape({
        proxy: string.isRequired,
      }).isRequired,
    }).isRequired,
  },

  getInitialState() {
    return {
      measurements: [],
      filterText: '',
    }
  },

  componentDidMount() {
    if (!this.props.query.database) {
      return
    }

    this._getMeasurements()
  },

  componentDidUpdate(prevProps) {
    const {query} = this.props

    if (!query.database) {
      return
    }

    if (prevProps.query.database === query.database) {
      return
    }

    this._getMeasurements()
  },

  handleFilterText(e) {
    e.stopPropagation()
    this.setState({
      filterText: this.refs.filterText.value,
    })
  },

  handleEscape(e) {
    if (e.key !== 'Escape') {
      return
    }

    e.stopPropagation()
    this.setState({
      filterText: '',
    })
  },

  handleAcceptReject(e) {
    e.stopPropagation()
    this.props.onToggleTagAcceptance()
  },

  render() {
    return (
      <div className="query-builder--column">
        <div className="query-builder--heading">
          <span>Measurements</span>
          {this.props.query.database
            ? <div className="query-builder--filter">
                <input
                  className="form-control input-sm"
                  ref="filterText"
                  placeholder="Filter"
                  type="text"
                  value={this.state.filterText}
                  onChange={this.handleFilterText}
                  onKeyUp={this.handleEscape}
                />
                <span className="icon search" />
              </div>
            : null}
        </div>
        {this.renderList()}
      </div>
    )
  },

  renderList() {
    if (!this.props.query.database) {
      return (
        <div className="query-builder--list-empty">
          <span>No <strong>Database</strong> selected</span>
        </div>
      )
    }

    const measurements = this.state.measurements.filter(m =>
      m.match(this.state.filterText)
    )

    return (
      <div className="query-builder--list">
        {measurements.map(measurement => {
          const isActive = measurement === this.props.query.measurement
          const numTagsActive = Object.keys(this.props.query.tags).length

          return (
            <div key={measurement}>
              <div className={classnames('query-builder--list-item', {active: isActive})}>
                <span onClick={isActive ? _.wrap(null, this.props.onChooseMeasurement) : _.wrap(measurement, this.props.onChooseMeasurement)}>
                  <div className="query-builder--caret icon caret-right"></div>
                  {measurement}
                </span>
                {(isActive && numTagsActive >= 1)
                  ? <div className={classnames('flip-toggle', {flipped: this.props.query.areTagsAccepted})} onClick={this.handleAcceptReject}>
                      <div className="flip-toggle--container">
                        <div className="flip-toggle--front">!=</div>
                        <div className="flip-toggle--back">=</div>
                      </div>
                    </div>
                  : null
                }
              </div>
              {
                isActive ?
                <TagList
                  query={this.props.query}
                  onChooseTag={this.props.onChooseTag}
                  onGroupByTag={this.props.onGroupByTag}
                />
                : null
              }
            </div>
          )
        })}
      </div>
    )
  },

  _getMeasurements() {
    const {source} = this.context
    const proxy = source.links.proxy
    showMeasurements(proxy, this.props.query.database).then(resp => {
      const {errors, measurementSets} = showMeasurementsParser(resp.data)
      if (errors.length) {
        // TODO: display errors in the UI.
        return console.error('InfluxDB returned error(s): ', errors) // eslint-disable-line no-console
      }

      this.setState({
        measurements: measurementSets[0].measurements,
      })
    })
  },
})

export default MeasurementList<commit_msg>Fixes bugs #1424,#1425<commit_after>import React, {PropTypes} from 'react'
import classnames from 'classnames'

import {showMeasurements} from 'shared/apis/metaQuery'
import showMeasurementsParser from 'shared/parsing/showMeasurements'
import TagList from './TagList'

const {func, shape, string} = PropTypes

const MeasurementList = React.createClass({
  propTypes: {
    query: shape({
      database: string,
      measurement: string,
    }).isRequired,
    onChooseMeasurement: func.isRequired,
    onChooseTag: func.isRequired,
    onToggleTagAcceptance: func.isRequired,
    onGroupByTag: func.isRequired,
  },

  contextTypes: {
    source: shape({
      links: shape({
        proxy: string.isRequired,
      }).isRequired,
    }).isRequired,
  },

  getInitialState() {
    return {
      measurements: [],
      filterText: '',
    }
  },

  componentDidMount() {
    if (!this.props.query.database) {
      return
    }

    this._getMeasurements()
  },

  componentDidUpdate(prevProps) {
    const {query} = this.props

    if (!query.database) {
      return
    }

    if (prevProps.query.database === query.database) {
      return
    }

    this._getMeasurements()
  },

  handleFilterText(e) {
    e.stopPropagation()
    this.setState({
      filterText: this.refs.filterText.value,
    })
  },

  handleEscape(e) {
    if (e.key !== 'Escape') {
      return
    }

    e.stopPropagation()
    this.setState({
      filterText: '',
    })
  },

  handleAcceptReject(e) {
    e.stopPropagation()
    this.props.onToggleTagAcceptance()
  },

  render() {
    return (
      <div className="query-builder--column">
        <div className="query-builder--heading">
          <span>Measurements</span>
          {this.props.query.database
            ? <div className="query-builder--filter">
                <input
                  className="form-control input-sm"
                  ref="filterText"
                  placeholder="Filter"
                  type="text"
                  value={this.state.filterText}
                  onChange={this.handleFilterText}
                  onKeyUp={this.handleEscape}
                />
                <span className="icon search" />
              </div>
            : null}
        </div>
        {this.renderList()}
      </div>
    )
  },

  renderList() {
    if (!this.props.query.database) {
      return (
        <div className="query-builder--list-empty">
          <span>No <strong>Database</strong> selected</span>
        </div>
      )
    }

    const measurements = this.state.measurements.filter(m =>
      m.match(this.state.filterText)
    )

    return (
      <div className="query-builder--list">
        {measurements.map(measurement => {
          const isActive = measurement === this.props.query.measurement
          const numTagsActive = Object.keys(this.props.query.tags).length

          return (
            <div
              key={measurement}
              onClick={
                isActive
                  ? () => {}
                  : () => this.props.onChooseMeasurement(measurement)
              }
            >
              <div
                className={classnames('query-builder--list-item', {
                  active: isActive,
                })}
              >
                <span>
                  <div className="query-builder--caret icon caret-right" />
                  {measurement}
                </span>
                {isActive && numTagsActive >= 1
                  ? <div
                      className={classnames('flip-toggle', {
                        flipped: this.props.query.areTagsAccepted,
                      })}
                      onClick={this.handleAcceptReject}
                    >
                      <div className="flip-toggle--container">
                        <div className="flip-toggle--front">!=</div>
                        <div className="flip-toggle--back">=</div>
                      </div>
                    </div>
                  : null}
              </div>
              {isActive
                ? <TagList
                    query={this.props.query}
                    onChooseTag={this.props.onChooseTag}
                    onGroupByTag={this.props.onGroupByTag}
                  />
                : null}
            </div>
          )
        })}
      </div>
    )
  },

  _getMeasurements() {
    const {source} = this.context
    const proxy = source.links.proxy
    showMeasurements(proxy, this.props.query.database).then(resp => {
      const {errors, measurementSets} = showMeasurementsParser(resp.data)
      if (errors.length) {
        // TODO: display errors in the UI.
        return console.error('InfluxDB returned error(s): ', errors) // eslint-disable-line no-console
      }

      this.setState({
        measurements: measurementSets[0].measurements,
      })
    })
  },
})

export default MeasurementList
{'fraction_non_alphanumeric': 0.1253629199502281, 'fraction_numerical': 0.001244296972210701, 'mean_word_length': 1.7062289562289563, 'pattern_counts': {'":': 0, '<': 72, '<?xml version=': 0, '>': 82, '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': '2396989', 'n_tokens_mistral': 2753, 'n_tokens_neox': 2627, 'n_words': 446}