{"changed":true,"filter":false,"title":"DataTable.jsx","tooltip":"/src/DataTable/DataTable.jsx","value":"import 'matches-selector-polyfill/dist/matches-selector-polyfill.js'\nimport {AgGridReact} from 'ag-grid-react'\nimport changeCase from 'change-case'\nimport {clearfix} from '../styles/general'\nimport debounce from 'lodash.debounce'\nimport {getSvgIcon} from '../utilities'\nimport Minus from 'material-ui/svg-icons/content/remove'\nimport Plus from 'material-ui/svg-icons/content/add'\nimport TextField from 'material-ui/TextField'\nimport React, {Component, PropTypes} from 'react'\n\nconst style = {\n  textField: {\n    float: 'right'\n  },\n  rowCount: {\n    fontWeight: 'normal',\n    fontSize: '14px',\n    margin: 0,\n    padding: '.25em',\n    textAlign: 'left'\n  }\n}\nconst csvDefaults = {\n  skipHeader: false,\n  skipFooters: false,\n  skipGroups: false,\n  allColumns: true,\n  onlySelected: false\n}\n\nexport class DataTable extends Component {\n  static propTypes = {\n    autoResize: PropTypes.bool,\n    checkboxColumn: PropTypes.any,\n    checkboxColumnConfig: PropTypes.object,\n    childProp: PropTypes.string,\n    columns: PropTypes.array,\n    containerStyle: PropTypes.object,\n    data: PropTypes.array.isRequired,\n    enableColResize: PropTypes.string,\n    enableFilter: PropTypes.string,\n    enableSorting: PropTypes.string,\n    exportFileName: PropTypes.string,\n    getNodeChildDetails: PropTypes.func,\n    resizeDelay: PropTypes.number,\n    stripeRows: PropTypes.bool\n  }\n\n  static defaultProps = {\n    autoResize: true,\n    checkboxColumn: false,\n    checkboxColumnConfig: {},\n    childProp: null,\n    columns: null,\n    containerStyle: {},\n    enableColResize: 'true',\n    enableFilter: 'true',\n    enableSorting: 'true',\n    exportFileName: 'table_export.csv',\n    resizeDelay: 100,\n    stripeRows: true\n  }\n\n  constructor (props) {\n    super(props)\n\n    this.state = {\n      quickFilterText: ''\n    }\n\n    this.defaultGroupingFn = ::this.defaultGroupingFn\n    this.onQuickFilterChange = ::this.onQuickFilterChange\n  }\n\n  handleReady = (params) => {\n    this.api = params.api\n    this.columnApi = params.columnApi\n\n    const gridWidth = params.api.gridPanel.eBody.clientWidth\n    const columnWidth = 200 * params.api.gridPanel.columnController.primaryColumns.length\n\n    if (columnWidth > gridWidth) {\n      return\n    }\n\n    this.handleResize()\n  }\n\n  redraw = () => {\n    this._container.style.display = 'none'\n    this._container.offsetHeight\n    this._container.style.display = 'block'\n  }\n\n  handleResize () {\n    if (!this.props.autoResize) {\n      return\n    }\n\n    this.api.sizeColumnsToFit()\n  }\n\n  shouldComponentUpdate (nextProps, nextState) {\n    if (this.state !== nextState) return true\n\n    return this.getChangedProps(this.props, nextProps).length !== 0\n  }\n\n  componentDidMount () {\n    const {grid} = this.refs\n    const {resizeDelay} = this.props\n\n    this.handleDebouncedResize = debounce(this.handleResize.bind(this, grid), resizeDelay)\n\n    window.addEventListener('resize', this.handleDebouncedResize)\n  }\n\n  componentDidUpdate (prevProps) {\n    this.handleResize(this.refs.grid)\n  }\n\n  componentWillUnmount () {\n    window.removeEventListener('resize', this.handleDebouncedResize)\n    this.api.destroy()\n  }\n\n  createColumns (data) {\n    const {childProp} = this.props\n    const [firstItem = {}] = data\n\n    const dataColumnKeys =\n      Object.keys(firstItem).filter((field) => (\n        !field.startsWith('_') && field !== childProp\n      ))\n\n    const drilldownColumnKeys =\n      Object.keys((firstItem[childProp] || [])[0] || {}).filter((field) => (\n        !field.startsWith('_')\n      ))\n\n    // Combine the columns names from both top level and child level fields.\n    // Create a Set to eliminate duplicates.\n    return [\n      ...new Set([\n        ...dataColumnKeys,\n        ...drilldownColumnKeys\n      ])]\n      .map((field) => ({\n        headerName: changeCase.titleCase(field),\n        field\n      }))\n  }\n\n  getChangedProps (oldProps, newProps) {\n    return Object.keys(newProps).filter((key) => {\n      return newProps[key] !== oldProps[key]\n    })\n  }\n\n  exportToCSV (exportParams = {}) {\n    const {exportFileName} = this.props\n\n    this.api.exportDataAsCsv({\n      fileName: exportFileName,\n      ...csvDefaults,\n      ...exportParams\n    })\n  }\n\n  getCSV (copyParams = {}) {\n    return this.api.getDataAsCsv({\n      ...csvDefaults,\n      ...copyParams\n    })\n  }\n\n  checkboxHeaderRendererFunc (params) {\n    const {api} = params\n    const cb = document.createElement('input')\n\n    cb.setAttribute('type', 'checkbox')\n    cb.setAttribute('class', 'ag-selection-checkbox')\n\n    const label = document.createElement('label')\n    const title = document.createTextNode(params.colDef.headerName)\n    const span = document.createElement('span')\n\n    span.setAttribute('class', 'ag-cell-value')\n    label.appendChild(cb)\n    label.appendChild(span)\n    label.appendChild(title)\n    cb.addEventListener('change', function (e) {\n      if (this.checked) {\n        api.selectAll()\n\n        return\n      }\n\n      api.deselectAll()\n    })\n\n    return label\n  }\n\n  tooltipRenderer (params) {\n    let renderedValue = params.value\n\n    // If there is another renderer that was saved off, call that renderer first.\n    if (params.previousCellRenderer !== undefined) {\n      renderedValue = params.previousCellRenderer.call(this, params)\n    }\n\n    return `<span title=\"${renderedValue}\">${renderedValue}</span>`\n  }\n\n  getGroupIcon (svgIcon) {\n    return getSvgIcon(svgIcon, {\n      style: {\n        cursor: 'pointer'\n      }\n    })\n  }\n\n  defaultGroupingFn (rowItem) {\n    const {childProp} = this.props\n\n    if (!rowItem[childProp]) {\n      return null\n    }\n\n    return {\n      children: rowItem[childProp],\n      group: true\n    }\n  }\n\n  onQuickFilterChange (ev, value) {\n    const {enableFilter} = this.props\n\n    if (enableFilter !== 'true') return\n\n    this.setState({\n      quickFilterText: value\n    })\n  }\n\n  render () {\n    const {\n      checkboxColumn,\n      checkboxColumnConfig,\n      childProp,\n      columns,\n      containerStyle,\n      data,\n      stripeRows\n    } = this.props\n    const {quickFilterText} = this.state\n    let columnDefs = columns || this.createColumns(data)\n    let gridProps = {\n      containerStyle,\n      headerHeight: '48',\n      rowHeight: '48',\n      suppressRowClickSelection: true,\n      onCellClicked: ({event}) => {\n        const {target} = event\n        const range = document.createRange()\n\n        if (!target.matches('.ag-cell')) {\n          return\n        }\n\n        range.selectNodeContents(target)\n\n        const selection = window.getSelection()\n\n        selection.removeAllRanges()\n        selection.addRange(range)\n      },\n      onGridReady: this.handleReady\n    }\n\n    // Go through each  column and change the tooltip\n    // property to the tooltip header renderer.\n    columnDefs = columnDefs.map((column) => {\n      if (column.enableTooltip === true) {\n        column.previousCellRenderer = column.cellRenderer\n        column.cellRenderer = this.tooltipRenderer\n      }\n\n      return column\n    })\n\n    // Add the row striping class to every other row\n    if (stripeRows === true) {\n      gridProps.getRowClass = (params) => {\n        return params.rowIndex % 2 === 1 ? 'ag-row-colored' : ''\n      }\n    }\n\n    // Add a new column containing the checkboxes along with header.\n    if (checkboxColumn) {\n      columnDefs = [{\n        ...checkboxColumnConfig,\n        checkboxSelection: true,\n        headerCellRenderer: this.checkboxHeaderRendererFunc,\n        headerName: '',\n        suppressMovable: true,\n        suppressResize: true,\n        suppressSorting: true,\n        width: 60,\n        onCellClicked: ({node}) => {\n          node.setSelected(!node.isSelected())\n        }\n      }, ...columnDefs]\n\n      // Setup the grid so that it properly checks/unchecks\n      gridProps = {\n        ...gridProps,\n        rowSelection: 'multiple'\n      }\n    }\n\n    if (childProp) {\n      gridProps.getNodeChildDetails = this.defaultGroupingFn\n\n      // Add the cell renderer to the first column to show children.\n      if (columnDefs.length > 0) {\n        columnDefs = [{\n          cellRenderer: 'group',\n          // headerCellRenderer: this.headerCellRendererFunc,\n          headerName: '',\n          suppressMovable: true,\n          suppressResize: true,\n          suppressSorting: true,\n          width: 100\n        }, ...columnDefs]\n\n        gridProps.icons = {\n          groupContracted: function () {\n            return this.getGroupIcon(Plus)\n          }.bind(this),\n          groupExpanded: function () {\n            return this.getGroupIcon(Minus)\n          }.bind(this)\n        }\n      }\n    }\n\n    gridProps = {\n      ...gridProps,\n      ...this.props,\n      quickFilterText,\n      columnDefs,\n      rowData: data\n    }\n\n    return (\n      <div\n        className='ag-material'\n        ref={(ref) => (this._container = ref)}\n      >\n        <TextField\n          floatingLabelText='Filter'\n          name='quickFilter'\n          style={style.textField}\n          onChange={this.onQuickFilterChange}\n        />\n        <div style={clearfix} />\n        <AgGridReact\n          ref='grid'\n          {...gridProps}\n        />\n        <p style={style.rowCount}>\n           Total rows: {data.length}\n        </p>\n      </div>\n    )\n  }\n}","undoManager":{"mark":100,"position":100,"stack":[[{"start":{"row":90,"column":23},"end":{"row":90,"column":24},"action":"insert","lines":["l"],"id":254}],[{"start":{"row":90,"column":24},"end":{"row":90,"column":25},"action":"insert","lines":["e"],"id":255}],[{"start":{"row":90,"column":25},"end":{"row":90,"column":26},"action":"insert","lines":["."],"id":256}],[{"start":{"row":90,"column":26},"end":{"row":90,"column":27},"action":"insert","lines":["d"],"id":257}],[{"start":{"row":90,"column":27},"end":{"row":90,"column":28},"action":"insert","lines":["i"],"id":258}],[{"start":{"row":90,"column":28},"end":{"row":90,"column":29},"action":"insert","lines":["s"],"id":259}],[{"start":{"row":90,"column":29},"end":{"row":90,"column":30},"action":"insert","lines":["p"],"id":260}],[{"start":{"row":90,"column":30},"end":{"row":90,"column":31},"action":"insert","lines":["l"],"id":261}],[{"start":{"row":90,"column":31},"end":{"row":90,"column":32},"action":"insert","lines":["a"],"id":262}],[{"start":{"row":90,"column":32},"end":{"row":90,"column":33},"action":"insert","lines":["y"],"id":263}],[{"start":{"row":90,"column":33},"end":{"row":90,"column":34},"action":"insert","lines":[" "],"id":264}],[{"start":{"row":90,"column":34},"end":{"row":90,"column":35},"action":"insert","lines":["="],"id":265}],[{"start":{"row":90,"column":35},"end":{"row":90,"column":36},"action":"insert","lines":[" "],"id":266}],[{"start":{"row":90,"column":36},"end":{"row":90,"column":38},"action":"insert","lines":["''"],"id":267}],[{"start":{"row":90,"column":37},"end":{"row":90,"column":38},"action":"insert","lines":["n"],"id":268}],[{"start":{"row":90,"column":38},"end":{"row":90,"column":39},"action":"insert","lines":["o"],"id":269}],[{"start":{"row":90,"column":39},"end":{"row":90,"column":40},"action":"insert","lines":["n"],"id":270}],[{"start":{"row":90,"column":40},"end":{"row":90,"column":41},"action":"insert","lines":["e"],"id":271}],[{"start":{"row":90,"column":42},"end":{"row":91,"column":0},"action":"insert","lines":["",""],"id":272},{"start":{"row":91,"column":0},"end":{"row":91,"column":4},"action":"insert","lines":["    "]}],[{"start":{"row":91,"column":4},"end":{"row":91,"column":5},"action":"insert","lines":["t"],"id":273}],[{"start":{"row":91,"column":5},"end":{"row":91,"column":6},"action":"insert","lines":["h"],"id":274}],[{"start":{"row":91,"column":6},"end":{"row":91,"column":7},"action":"insert","lines":["s"],"id":275}],[{"start":{"row":91,"column":7},"end":{"row":91,"column":8},"action":"insert","lines":["."],"id":276}],[{"start":{"row":91,"column":8},"end":{"row":91,"column":9},"action":"insert","lines":["_"],"id":277}],[{"start":{"row":91,"column":9},"end":{"row":91,"column":10},"action":"insert","lines":["c"],"id":278}],[{"start":{"row":91,"column":10},"end":{"row":91,"column":11},"action":"insert","lines":["o"],"id":279}],[{"start":{"row":91,"column":11},"end":{"row":91,"column":12},"action":"insert","lines":["n"],"id":280}],[{"start":{"row":91,"column":12},"end":{"row":91,"column":13},"action":"insert","lines":["t"],"id":281}],[{"start":{"row":91,"column":13},"end":{"row":91,"column":14},"action":"insert","lines":["a"],"id":282}],[{"start":{"row":91,"column":14},"end":{"row":91,"column":15},"action":"insert","lines":["i"],"id":283}],[{"start":{"row":91,"column":15},"end":{"row":91,"column":16},"action":"insert","lines":["n"],"id":284}],[{"start":{"row":91,"column":16},"end":{"row":91,"column":17},"action":"insert","lines":["e"],"id":285}],[{"start":{"row":91,"column":17},"end":{"row":91,"column":18},"action":"insert","lines":["r"],"id":286}],[{"start":{"row":91,"column":18},"end":{"row":91,"column":19},"action":"insert","lines":["."],"id":287}],[{"start":{"row":91,"column":19},"end":{"row":91,"column":20},"action":"insert","lines":["o"],"id":288}],[{"start":{"row":91,"column":20},"end":{"row":91,"column":21},"action":"insert","lines":["f"],"id":289}],[{"start":{"row":91,"column":21},"end":{"row":91,"column":22},"action":"insert","lines":["f"],"id":290}],[{"start":{"row":91,"column":22},"end":{"row":91,"column":23},"action":"insert","lines":["s"],"id":291}],[{"start":{"row":91,"column":23},"end":{"row":91,"column":24},"action":"insert","lines":["e"],"id":292}],[{"start":{"row":91,"column":24},"end":{"row":91,"column":25},"action":"insert","lines":["t"],"id":293}],[{"start":{"row":91,"column":25},"end":{"row":91,"column":26},"action":"insert","lines":["H"],"id":294}],[{"start":{"row":91,"column":26},"end":{"row":91,"column":27},"action":"insert","lines":["e"],"id":295}],[{"start":{"row":91,"column":27},"end":{"row":91,"column":28},"action":"insert","lines":["i"],"id":296}],[{"start":{"row":91,"column":28},"end":{"row":91,"column":29},"action":"insert","lines":["g"],"id":297}],[{"start":{"row":91,"column":29},"end":{"row":91,"column":30},"action":"insert","lines":["h"],"id":298}],[{"start":{"row":91,"column":30},"end":{"row":91,"column":31},"action":"insert","lines":["t"],"id":299}],[{"start":{"row":91,"column":6},"end":{"row":91,"column":7},"action":"insert","lines":["i"],"id":300}],[{"start":{"row":91,"column":32},"end":{"row":92,"column":0},"action":"insert","lines":["",""],"id":301},{"start":{"row":92,"column":0},"end":{"row":92,"column":4},"action":"insert","lines":["    "]}],[{"start":{"row":92,"column":4},"end":{"row":92,"column":5},"action":"insert","lines":["t"],"id":302}],[{"start":{"row":92,"column":5},"end":{"row":92,"column":6},"action":"insert","lines":["h"],"id":303}],[{"start":{"row":92,"column":6},"end":{"row":92,"column":7},"action":"insert","lines":["i"],"id":304}],[{"start":{"row":92,"column":7},"end":{"row":92,"column":8},"action":"insert","lines":["s"],"id":305}],[{"start":{"row":92,"column":8},"end":{"row":92,"column":9},"action":"insert","lines":["."],"id":306}],[{"start":{"row":92,"column":9},"end":{"row":92,"column":10},"action":"insert","lines":["_"],"id":307}],[{"start":{"row":92,"column":10},"end":{"row":92,"column":11},"action":"insert","lines":["c"],"id":308}],[{"start":{"row":92,"column":11},"end":{"row":92,"column":12},"action":"insert","lines":["o"],"id":309}],[{"start":{"row":92,"column":12},"end":{"row":92,"column":13},"action":"insert","lines":["n"],"id":310}],[{"start":{"row":92,"column":13},"end":{"row":92,"column":14},"action":"insert","lines":["t"],"id":311}],[{"start":{"row":92,"column":14},"end":{"row":92,"column":15},"action":"insert","lines":["a"],"id":312}],[{"start":{"row":92,"column":15},"end":{"row":92,"column":16},"action":"insert","lines":["i"],"id":313}],[{"start":{"row":92,"column":16},"end":{"row":92,"column":17},"action":"insert","lines":["n"],"id":314}],[{"start":{"row":92,"column":17},"end":{"row":92,"column":18},"action":"insert","lines":["e"],"id":315}],[{"start":{"row":92,"column":18},"end":{"row":92,"column":19},"action":"insert","lines":["r"],"id":316}],[{"start":{"row":92,"column":19},"end":{"row":92,"column":20},"action":"insert","lines":["."],"id":317}],[{"start":{"row":92,"column":20},"end":{"row":92,"column":21},"action":"insert","lines":["s"],"id":318}],[{"start":{"row":92,"column":21},"end":{"row":92,"column":22},"action":"insert","lines":["t"],"id":319}],[{"start":{"row":92,"column":22},"end":{"row":92,"column":23},"action":"insert","lines":["y"],"id":320}],[{"start":{"row":92,"column":23},"end":{"row":92,"column":24},"action":"insert","lines":["l"],"id":321}],[{"start":{"row":92,"column":24},"end":{"row":92,"column":25},"action":"insert","lines":["e"],"id":322}],[{"start":{"row":92,"column":25},"end":{"row":92,"column":26},"action":"insert","lines":["."],"id":323}],[{"start":{"row":92,"column":26},"end":{"row":92,"column":27},"action":"insert","lines":["d"],"id":324}],[{"start":{"row":92,"column":27},"end":{"row":92,"column":28},"action":"insert","lines":["i"],"id":325}],[{"start":{"row":92,"column":28},"end":{"row":92,"column":29},"action":"insert","lines":["s"],"id":326}],[{"start":{"row":92,"column":29},"end":{"row":92,"column":30},"action":"insert","lines":["p"],"id":327}],[{"start":{"row":92,"column":30},"end":{"row":92,"column":31},"action":"insert","lines":["l"],"id":328}],[{"start":{"row":92,"column":31},"end":{"row":92,"column":32},"action":"insert","lines":["a"],"id":329}],[{"start":{"row":92,"column":32},"end":{"row":92,"column":33},"action":"insert","lines":["y"],"id":330}],[{"start":{"row":92,"column":33},"end":{"row":92,"column":34},"action":"insert","lines":[" "],"id":331}],[{"start":{"row":92,"column":34},"end":{"row":92,"column":35},"action":"insert","lines":["="],"id":332}],[{"start":{"row":92,"column":35},"end":{"row":92,"column":36},"action":"insert","lines":[" "],"id":333}],[{"start":{"row":92,"column":36},"end":{"row":92,"column":38},"action":"insert","lines":["''"],"id":334}],[{"start":{"row":92,"column":37},"end":{"row":92,"column":38},"action":"insert","lines":["b"],"id":335}],[{"start":{"row":92,"column":38},"end":{"row":92,"column":39},"action":"insert","lines":["l"],"id":336}],[{"start":{"row":92,"column":39},"end":{"row":92,"column":40},"action":"insert","lines":["o"],"id":337}],[{"start":{"row":92,"column":40},"end":{"row":92,"column":41},"action":"insert","lines":["c"],"id":338}],[{"start":{"row":92,"column":41},"end":{"row":92,"column":42},"action":"insert","lines":["k"],"id":339}],[{"start":{"row":89,"column":2},"end":{"row":89,"column":8},"action":"remove","lines":["resize"],"id":340},{"start":{"row":89,"column":2},"end":{"row":89,"column":3},"action":"insert","lines":["r"]}],[{"start":{"row":89,"column":3},"end":{"row":89,"column":4},"action":"insert","lines":["e"],"id":341}],[{"start":{"row":89,"column":4},"end":{"row":89,"column":5},"action":"insert","lines":["d"],"id":342}],[{"start":{"row":89,"column":5},"end":{"row":89,"column":6},"action":"insert","lines":["r"],"id":343}],[{"start":{"row":89,"column":6},"end":{"row":89,"column":7},"action":"insert","lines":["a"],"id":344}],[{"start":{"row":89,"column":7},"end":{"row":89,"column":8},"action":"insert","lines":["w"],"id":345}],[{"start":{"row":358,"column":10},"end":{"row":358,"column":11},"action":"remove","lines":[" "],"id":346}],[{"start":{"row":358,"column":10},"end":{"row":359,"column":0},"action":"insert","lines":["",""],"id":347},{"start":{"row":359,"column":0},"end":{"row":359,"column":6},"action":"insert","lines":["      "]}],[{"start":{"row":359,"column":6},"end":{"row":359,"column":8},"action":"insert","lines":["  "],"id":348}],[{"start":{"row":359,"column":31},"end":{"row":359,"column":32},"action":"remove","lines":[" "],"id":349}],[{"start":{"row":359,"column":31},"end":{"row":360,"column":0},"action":"insert","lines":["",""],"id":350},{"start":{"row":360,"column":0},"end":{"row":360,"column":8},"action":"insert","lines":["        "]}],[{"start":{"row":360,"column":44},"end":{"row":361,"column":0},"action":"insert","lines":["",""],"id":351},{"start":{"row":361,"column":0},"end":{"row":361,"column":8},"action":"insert","lines":["        "]}],[{"start":{"row":361,"column":6},"end":{"row":361,"column":8},"action":"remove","lines":["  "],"id":352}],[{"start":{"row":360,"column":22},"end":{"row":360,"column":23},"action":"insert","lines":["("],"id":353}],[{"start":{"row":360,"column":44},"end":{"row":360,"column":45},"action":"insert","lines":[")"],"id":354}],[{"start":{"row":89,"column":4},"end":{"row":89,"column":5},"action":"insert","lines":["s"],"id":357}],[{"start":{"row":89,"column":3},"end":{"row":89,"column":4},"action":"insert","lines":["e"],"id":357}],[{"start":{"row":89,"column":2},"end":{"row":89,"column":8},"action":"remove","lines":["redraw"],"id":358},{"start":{"row":89,"column":2},"end":{"row":89,"column":3},"action":"insert","lines":["r"]}]]},"ace":{"folds":[],"scrolltop":1468,"scrollleft":0,"selection":{"start":{"row":101,"column":3},"end":{"row":101,"column":3},"isBackwards":false},"options":{"guessTabSize":true,"useWrapMode":false,"wrapToView":true},"firstLineState":0},"timestamp":1475068481680}