Repository: h2oai/wave
File: ui/src/table.tsx (TypeScript)

Code before:
      : b > a ? 1 : -1
  },
  formatNum = (num: U) => num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","),
  toCSV = (data: unknown[][]): S => data.map(row => {
    const line = JSON.stringify(row)
    return line.substr(1, line.length - 2)
  }).join('\n'),
  ContextualMenu = ({ onFilterChange, col, listProps, selectedFiltersRef, setFiltersInBulk }: ContextualMenuState) => {
    const
      isFilterChecked = (data: S, key: S) => !!selectedFiltersRef.current && selectedFiltersRef.current[data]?.includes(key),
      [filters, setFilters] = React.useState(col.cellType?.tag
        ? Array.from(listProps.items.reduce((_filters, { key, text, data }) => {
          key.split(',').forEach(key => _filters.set(key, { key, text, data }))
          return _filters
        }, new Map<S, Fluent.IContextualMenuItem>()).values())
        : listProps.items.map(i => ({ ...i, checked: isFilterChecked(i.data, i.key) }))
      ),
      selectAll = () => {
        setFilters(filters.map(i => ({ ...i, checked: true })))
        setFiltersInBulk(col.key, filters.map(f => f.key))
      },
      deselectAll = () => {
        setFilters(filters.map(i => ({ ...i, checked: false })))
        setFiltersInBulk(col.key, [])
      },
      getOnFilterChangeHandler = (data: S, key: S) => (_ev?: React.FormEvent<HTMLInputElement | HTMLElement>, checked?: boolean) => {
        setFilters(filters => filters.map(f => f.key === key ? ({ ...f, checked }) : f))
        onFilterChange(data, key, checked)
      }

    return (
      <div style={{ padding: 10 }}>
        <Fluent.Text variant='mediumPlus' styles={{ root: { paddingTop: 10, paddingBottom: 10, fontWeight: 'bold' } }} block>Show only</Fluent.Text>
        <Fluent.Text variant='small'>
          <Fluent.Link onClick={selectAll}>Select All</Fluent.Link> | <Fluent.Link onClick={deselectAll}>Deselect All</Fluent.Link>
        </Fluent.Text>
        {
          filters.map(({ key, data, checked }) => (
            <Fluent.Checkbox
              key={key}
              label={key}
              checked={checked}
              onChange={getOnFilterChangeHandler(data, key)}
              styles={{ root: { marginBottom: 5 } }}
            />
          )
          )
        }
      </div>
    )
  },

Review comment (suggestion):
Odd naming, handlers usually start with on rather than get.

nit
```suggestion
      getOnFilterChangeHandler = (data: S, key: S) => (_ev?: React.FormEvent<HTMLInputElement | HTMLElement>, checked?: B) => {
```

Code after:
      : b > a ? 1 : -1
  },
  formatNum = (num: U) => num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","),
  toCSV = (data: unknown[][]): S => data.map(row => {
    const line = JSON.stringify(row)
    return line.substr(1, line.length - 2)
  }).join('\n'),
  ContextualMenu = ({ onFilterChange, col, listProps, selectedFiltersRef, setFiltersInBulk }: ContextualMenuProps) => {
    const
      isFilterChecked = (data: S, key: S) => !!selectedFiltersRef.current && selectedFiltersRef.current[data]?.includes(key),
      [menuFilters, setMenuFilters] = React.useState(col.cellType?.tag
        ? Array.from(listProps.items.reduce((_filters, { key, text, data }) => {
          key.split(',').forEach(key => _filters.set(key, { key, text, data, checked: isFilterChecked(data, key) }))
          return _filters
        }, new Map<S, Fluent.IContextualMenuItem>()).values())
        : listProps.items.map(i => ({ ...i, checked: isFilterChecked(i.data, i.key) }))
      ),
      selectAll = () => {
        setMenuFilters(menuFilters.map(i => ({ ...i, checked: true })))
        setFiltersInBulk(col.key, menuFilters.map(f => f.key))
      },
      deselectAll = () => {
        setMenuFilters(menuFilters.map(i => ({ ...i, checked: false })))
        setFiltersInBulk(col.key, [])
      },
      getOnFilterChangeHandler = (data: S, key: S) => (_ev?: React.FormEvent<HTMLInputElement | HTMLElement>, checked?: B) => {
        setMenuFilters(filters => filters.map(f => f.key === key ? ({ ...f, checked }) : f))
        onFilterChange(data, key, checked)
      }

    return (
      <div style={{ padding: 10 }}>
        <Fluent.Text variant='mediumPlus' styles={{ root: { paddingTop: 10, paddingBottom: 10, fontWeight: 'bold' } }} block>Show only</Fluent.Text>
        <Fluent.Text variant='small'>
          <Fluent.Link onClick={selectAll}>Select All</Fluent.Link> | <Fluent.Link onClick={deselectAll}>Deselect All</Fluent.Link>
        </Fluent.Text>
        {
          menuFilters.map(({ key, data, checked }) => (
            <Fluent.Checkbox
              key={key}
              label={key}
              checked={checked}
              onChange={getOnFilterChangeHandler(data, key)}
              styles={{ root: { marginBottom: 5 } }}
            />
          )
          )
        }
      </div>
    )
  },