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

87.23% Statements 41/47
70% Branches 7/10
50% Functions 6/12
88.89% Lines 40/45
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 132 133                                                       153×   153×                             192×   29×     153×                                                                                                
import React from 'react';
import PropTypes from 'prop-types';
import {
  Label, Row, Col, FormControl, Modal, OverlayTrigger,
  Tooltip } from 'react-bootstrap';
import visTypes from '../../visTypes';
import ControlHeader from '../ControlHeader';
import { t } from '../../../locales';
 
const propTypes = {
  description: PropTypes.string,
  label: PropTypes.string,
  name: PropTypes.string.isRequired,
  onChange: PropTypes.func,
  value: PropTypes.string.isRequired,
};
 
const defaultProps = {
  onChange: () => {},
};
 
export default class VizTypeControl extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      showModal: false,
      filter: '',
    };
    this.toggleModal = this.toggleModal.bind(this);
    this.changeSearch = this.changeSearch.bind(this);
    this.setSearchRef = this.setSearchRef.bind(this);
    this.focusSearch = this.focusSearch.bind(this);
  }
  onChange(vizType) {
    this.props.onChange(vizType);
    this.setState({ showModal: false });
  }
  setSearchRef(searchRef) {
    this.searchRef = searchRef;
  }
  toggleModal() {
    this.setState({ showModal: !this.state.showModal });
  }
  changeSearch(event) {
    this.setState({ filter: event.target.value });
  }
  focusSearch() {
    if (this.searchRef) {
      this.searchRef.focus();
    }
  }
  renderVizType(vizType) {
    const vt = vizType;
    return (
      <div
        className={`viztype-selector-container ${vt === this.props.value ? 'selected' : ''}`}
        onClick={this.onChange.bind(this, vt)}
      >
        <img
          alt={`viz-type-${vt}`}
          width="100%"
          className={`viztype-selector ${this.props.value === vt ? 'selected' : ''}`}
          src={`/static/assets/images/viz_thumbnails/${vt}.png`}
        />
        <div className="viztype-label">
          {visTypes[vt].label}
        </div>
      </div>);
  }
  render() {
    const filter = this.state.filter;
    const filteredVizTypes = Object.keys(visTypes)
      .filter(vt => filter.length === 0 || visTypes[vt].label.toLowerCase().includes(filter));
 
    const imgPerRow = 6;
    const rows = [];
    for (let i = 0; i <= filteredVizTypes.length; i += imgPerRow) {
      rows.push(
        <Row key={`row-${i}`}>
          {filteredVizTypes.slice(i, i + imgPerRow).map(vt => (
            <Col md={12 / imgPerRow} key={`grid-col-${vt}`}>
              {this.renderVizType(vt)}
            </Col>
          ))}
        </Row>);
    }
    return (
      <div>
        <ControlHeader
          {...this.props}
        />
        <OverlayTrigger
          placement="right"
          overlay={
            <Tooltip id={'error-tooltip'}>Click to change visualization type</Tooltip>
          }
        >
          <Label onClick={this.toggleModal} style={{ cursor: 'pointer' }}>
            {visTypes[this.props.value].label}
          </Label>
        </OverlayTrigger>
        <Modal
          show={this.state.showModal}
          onHide={this.toggleModal}
          onEnter={this.focusSearch}
          onExit={this.setSearchRef}
          bsSize="lg"
        >
          <Modal.Header closeButton>
            <Modal.Title>{t('Select a visualization type')}</Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <div>
              <FormControl
                id="formControlsText"
                inputRef={(ref) => { this.setSearchRef(ref); }}
                type="text"
                bsSize="sm"
                value={this.state.filter}
                placeholder={t('Search / Filter')}
                onChange={this.changeSearch}
              />
            </div>
            {rows}
          </Modal.Body>
        </Modal>
      </div>);
  }
}
 
VizTypeControl.propTypes = propTypes;
VizTypeControl.defaultProps = defaultProps;