all files / src/explore/components/controls/ FixedOrMetricControl.jsx

83.33% Statements 40/48
61.54% Branches 16/26
25% Functions 3/12
90.7% Lines 39/43
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131                                                                                                                                                                                        
import React from 'react';
import PropTypes from 'prop-types';
import { Label, Popover, OverlayTrigger } from 'react-bootstrap';
 
import controls from '../../controls';
import TextControl from './TextControl';
import SelectControl from './SelectControl';
import ControlHeader from '../ControlHeader';
import PopoverSection from '../../../components/PopoverSection';
 
const controlTypes = {
  fixed: 'fix',
  metric: 'metric',
};
 
const propTypes = {
  onChange: PropTypes.func,
  value: PropTypes.object,
  isFloat: PropTypes.bool,
  datasource: PropTypes.object,
  default: PropTypes.shape({
    type: PropTypes.oneOf(['fix', 'metric']),
    value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  }),
};
 
const defaultProps = {
  onChange: () => {},
  default: { type: controlTypes.fixed, value: 5 },
};
 
export default class FixedOrMetricControl extends React.Component {
  constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
    this.setType = this.setType.bind(this);
    this.setFixedValue = this.setFixedValue.bind(this);
    this.setMetric = this.setMetric.bind(this);
    const type = (props.value ? props.value.type : props.default.type) || controlTypes.fixed;
    const value = (props.value ? props.value.value : props.default.value) || '100';
    this.state = {
      type,
      fixedValue: type === controlTypes.fixed ? value : '',
      metricValue: type === controlTypes.metric ? value : null,
    };
  }
  onChange() {
    this.props.onChange({
      type: this.state.type,
      value: this.state.type === controlTypes.fixed ?
        this.state.fixedValue : this.state.metricValue,
    });
  }
  setType(type) {
    this.setState({ type }, this.onChange);
  }
  setFixedValue(fixedValue) {
    this.setState({ fixedValue }, this.onChange);
  }
  setMetric(metricValue) {
    this.setState({ metricValue }, this.onChange);
  }
  renderPopover() {
    const value = this.props.value || this.props.default;
    const type = value.type || controlTypes.fixed;
    const metrics = this.props.datasource ? this.props.datasource.metrics : null;
    return (
      <Popover id="filter-popover">
        <div style={{ width: '240px' }}>
          <PopoverSection
            title="Fixed"
            isSelected={type === controlTypes.fixed}
            onSelect={() => { this.onChange(controlTypes.fixed); }}
          >
            <TextControl
              isFloat
              onChange={this.setFixedValue}
              onFocus={() => { this.setType(controlTypes.fixed); }}
              value={this.state.fixedValue}
            />
          </PopoverSection>
          <PopoverSection
            title="Based on a metric"
            isSelected={type === controlTypes.metric}
            onSelect={() => { this.onChange(controlTypes.metric); }}
          >
            <SelectControl
              {...controls.metric}
              name="metric"
              options={metrics}
              onFocus={() => { this.setType(controlTypes.metric); }}
              onChange={this.setMetric}
              value={this.state.metricValue}
            />
          </PopoverSection>
        </div>
      </Popover>
    );
  }
  render() {
    return (
      <div>
        <ControlHeader {...this.props} />
        <OverlayTrigger
          container={document.body}
          trigger="click"
          rootClose
          ref="trigger"
          placement="right"
          overlay={this.renderPopover()}
        >
          <Label style={{ cursor: 'pointer' }}>
            {this.state.type === controlTypes.fixed &&
              <span>{this.state.fixedValue}</span>
            }
            {this.state.type === controlTypes.metric &&
              <span>
                <span style={{ fontWeight: 'normal' }}>metric: </span>
                <strong>{this.state.metricValue}</strong>
              </span>
            }
          </Label>
        </OverlayTrigger>
      </div>
    );
  }
}
 
FixedOrMetricControl.propTypes = propTypes;
FixedOrMetricControl.defaultProps = defaultProps;