All files / src/gadgets/list filter-dialog.js

100% Statements 18/18
100% Branches 7/7
100% Functions 11/11
100% Lines 18/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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                                                              8x 8x           2x 2x   2x 1x     2x       1x           1x       1x       9x 9x   9x   31x     31x           9x 1x                                                   22x                                      
/* Copyright © 2016 Kuali, Inc. - All Rights Reserved
 * You may use and modify this code under the terms of the Kuali, Inc.
 * Pre-Release License Agreement. You may not distribute it.
 *
 * You should have received a copy of the Kuali, Inc. Pre-Release License
 * Agreement with this file. If not, please write to license@kuali.co.
 */
 
import PropTypes from 'prop-types'
import React from 'react'
import styles from './filter-dialog.css'
import { Checkbox, FlatButton, Icon, TextField } from '@kuali/kuali-ui'
import { includes, isEmpty, noop, partial, uniq } from 'lodash'
 
export default class FilterDialog extends React.Component {
  static propTypes = {
    colKey: PropTypes.string,
    rows: PropTypes.array,
    labelForValue: PropTypes.func.isRequired,
    hiddenValues: PropTypes.array,
    updateHiddenValues: PropTypes.func
  }
 
  static defaultProps = {
    rows: [],
    colKey: '',
    hiddenValues: [],
    updateHiddenValues: noop
  }
 
  constructor (props) {
    super(props)
    this.state = {
      filterFindText: ''
    }
  }
 
  handleFilterValueChecked = (colKey, checked, e) => {
    const value = e.target.value
    const { hiddenValues } = this.props
 
    const newHidden = checked
      ? hiddenValues.filter(v => v !== value) // Remove the value from hidden
      : uniq([...hiddenValues, value]) // Add the value to hidden
 
    this.props.updateHiddenValues(newHidden)
  }
 
  handleFilterFindTextChanged = filterFindText => {
    this.setState({
      filterFindText
    })
  }
 
  handleSelectAllClicked = () => {
    this.props.updateHiddenValues([]) // Don't hide any of them
  }
 
  handleClearAllClicked = (values, e) => {
    this.props.updateHiddenValues(values) // Hide all of the values
  }
 
  render () {
    const { colKey, hiddenValues, labelForValue, rows } = this.props
    const { filterFindText } = this.state
    // Get unique values for the dialog
    const values = uniq(
      rows
        .map(row => row[colKey])
        .filter(
          val =>
            !isEmpty(val) &&
            (isEmpty(filterFindText) ||
              val.toLowerCase().indexOf(filterFindText.toLowerCase()) !== -1)
        )
    ).sort()
 
    return (
      <div className={styles.filterDialog} onClick={e => e.stopPropagation()}>
        {/* search bar */}
        <TextField
          style={{ marginBottom: '10px' }}
          leftIcon={<Icon name='search' />}
          placeholder='Find'
          value={filterFindText}
          onChange={this.handleFilterFindTextChanged}
        />
        {/* select all / clear all buttons */}
        <div style={{ display: 'flex', marginBottom: '10px' }}>
          <FlatButton
            className={styles.filterControlButton}
            label='Select All'
            onClick={this.handleSelectAllClicked}
          />
          <FlatButton
            className={styles.filterControlButton}
            label='Clear All'
            onClick={partial(this.handleClearAllClicked, values)}
          />
        </div>
        {/* list of values with checkboxes */}
        <div className={styles.filterValues}>
          <div>
            {values.map(value => (
              <Checkbox
                id={`filter-${colKey}-${value}`}
                key={value}
                label={labelForValue(colKey, value)}
                name={colKey}
                value={value}
                checked={!includes(hiddenValues, value)}
                onChange={partial(this.handleFilterValueChecked, colKey)}
              />
            ))}
            {isEmpty(values) && (
              <div style={{ margin: '10px 0' }}>No values</div>
            )}
          </div>
        </div>
      </div>
    )
  }
}