Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
Merge pull request #3 from HospitalRun/master
Browse files Browse the repository at this point in the history
Updating fork
  • Loading branch information
JDarke authored Jun 22, 2020
2 parents a75b4d4 + b525790 commit 9def991
Show file tree
Hide file tree
Showing 8 changed files with 248 additions and 1,170 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# [1.13.0](https://github.com/HospitalRun/components/compare/v1.12.2...v1.13.0) (2020-06-18)


### Features

* **table:** update table ([#455](https://github.com/HospitalRun/components/issues/455)) ([7ff5648](https://github.com/HospitalRun/components/commit/7ff56485ed7a67af9e7c1808c49a28cc0e02a21e))

## [1.12.2](https://github.com/HospitalRun/components/compare/v1.12.1...v1.12.2) (2020-06-16)


Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hospitalrun/components",
"version": "1.12.2",
"version": "1.13.0",
"license": "MIT",
"funding": {
"type": "opencollective",
Expand Down Expand Up @@ -98,11 +98,11 @@
"enzyme": "~3.11.0",
"enzyme-adapter-react-16": "~1.15.2",
"eslint": "~7.2.0",
"eslint-config-airbnb": "~18.1.0",
"eslint-config-airbnb": "~18.2.0",
"eslint-config-prettier": "~6.11.0",
"eslint-plugin-import": "~2.21.1",
"eslint-plugin-jest": "~23.13.1",
"eslint-plugin-jsx-a11y": "~6.2.3",
"eslint-plugin-jsx-a11y": "~6.3.0",
"eslint-plugin-prettier": "~3.1.1",
"eslint-plugin-react": "~7.20.0",
"eslint-plugin-react-hooks": "~4.0.1",
Expand Down Expand Up @@ -137,13 +137,13 @@
"@fullcalendar/timegrid": "~4.4.2",
"@tinymce/tinymce-react": "~3.6.0",
"@types/react-bootstrap-typeahead": "^3.4.6",
"@types/react-datepicker": "~2.11.0",
"@types/react-datepicker": "~3.0.0",
"babel-jest": "~26.0.1",
"chart.js": "~2.9.3",
"date-fns": "~2.9.0",
"date-fns": "~2.14.0",
"formik": "~2.1.0",
"lodash": "~4.17.15",
"moment": "~2.26.0",
"moment": "~2.27.0",
"react-bootstrap-typeahead": "^4.2.3",
"react-datepicker": "~3.0.0",
"react-spinners": "~0.8.3",
Expand Down
210 changes: 74 additions & 136 deletions src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,151 +1,89 @@
import React from 'react'
import { useTable, useFilters, useSortBy, usePagination, TableInstance } from 'react-table'
import { ButtonVariant } from 'src/interfaces'

import { generateColumns } from './helper'
import { Data, TableProperties, GeneratedColumn } from './interfaces'
import { Button } from '../Button'

type T = { [key: string]: any }

interface Props {
/** TableProperties are composed by a tableClassname string property and the columns array */
tableProperties: TableProperties
/** Provides data for the table */
data?: Data[]
tableClassName: string
headerClassName: string
columns: { key: string; label: string; formatter?: (row: T) => React.ReactNode }[]
data: T[]
actionsHeaderText: string
actions?: { label: string; action: (row: T) => void; buttonColor?: ButtonVariant }[]
getID: (row: T) => string
onRowClick?: (row: T) => void
}

function Table({ data, tableProperties }: Props) {
const columns = React.useMemo(() => generateColumns(tableProperties.columns), [])

const Table = (props: Props) => {
const {
getTableProps,
getTableBodyProps,
headerGroups,
page,
prepareRow,
canPreviousPage,
canNextPage,
pageOptions,
pageCount,
gotoPage,
nextPage,
previousPage,
setPageSize,
state: { pageIndex, pageSize },
} = useTable<Data>(
{
columns,
data: data || [],
initialState: { pageIndex: 0 },
},
useFilters,
useSortBy,
usePagination,
) as TableInstance<Record<string, unknown>>

return (
<>
<table {...getTableProps()} className={tableProperties.tableClassname}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column: GeneratedColumn) => (
<th
{...column.getHeaderProps()}
className={column.headerClassName ? column.headerClassName : ''}
>
<div {...(column.disableSorting ? null : column.getSortByToggleProps())}>
{column.render('Header')}
<span>{column.isSorted ? (column.isSortedDesc ? ' 🔽' : ' 🔼') : ''}</span>
</div>
tableClassName,
headerClassName,
columns,
data,
actionsHeaderText,
actions,
getID,
onRowClick,
} = props

<div>{!column.disableFiltering && column.render('Filter')}</div>
</th>
))}
</tr>
const table = (
<table className={tableClassName}>
<thead className={headerClassName}>
<tr>
{columns.map((column) => (
<th key={column.key}>{column.label}</th>
))}
</thead>
<tbody {...getTableBodyProps()}>
{page.map((row) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell: any) => (
<td
{...cell.getCellProps()}
className={cell.column.className ? cell.column.className : ''}
{actions ? <th>{actionsHeaderText}</th> : null}
</tr>
</thead>

<tbody>
{data.map((row: T) => (
<tr
key={getID(row)}
onClick={() => {
if (onRowClick) {
onRowClick(row)
}
}}
>
{columns.map((column) => {
const content = !column.formatter ? row[column.key] : column.formatter(row)
return <td key={`${column.key}-${getID(row)}`}>{content}</td>
})}

{actions ? (
<td>
{actions.map(({ label, action, buttonColor }, i) => (
<Button
key={label}
color={buttonColor || 'primary'}
onClick={(e) => {
e.stopPropagation()
action(row)
}}
className={i > 0 ? 'ml-1' : ''}
>
{cell.render('Cell')}
</td>
{label}
</Button>
))}
</tr>
)
})}
</tbody>
</table>
<div className="pagination">
<button
type="button"
id="firstPageButton"
onClick={() => gotoPage(0)}
disabled={!canPreviousPage}
>
{'<<'}
</button>{' '}
<button
type="button"
id="previousPageButton"
onClick={() => previousPage()}
disabled={!canPreviousPage}
>
{'<'}
</button>{' '}
<button
type="button"
id="nextPageButton"
onClick={() => nextPage()}
disabled={!canNextPage}
>
{'>'}
</button>{' '}
<button
type="button"
id="lastPageButton"
onClick={() => gotoPage(pageCount - 1)}
disabled={!canNextPage}
>
{'>>'}
</button>{' '}
<span>
Page{' '}
<strong>
{data && data.length ? pageIndex + 1 : pageIndex} of {pageOptions.length}
</strong>{' '}
</span>
<span>
| Go to page:{' '}
<input
type="number"
defaultValue={pageIndex + 1}
onChange={(e) => {
const p = e.target.value ? Number(e.target.value) - 1 : 0
gotoPage(p)
}}
style={{ width: '100px' }}
/>
</span>{' '}
<select
value={pageSize}
onChange={(e) => {
setPageSize(Number(e.target.value))
}}
>
{[10, 20, 30, 40, 50].map((pageS) => (
<option key={pageS} value={pageS}>
Show {pageS}
</option>
))}
</select>
</div>
</>
</td>
) : null}
</tr>
))}
</tbody>
</table>
)

return table
}

Table.defaultProps = {
tableClassName: 'table table-hover',
headerClassName: 'thead-light',
actionsHeaderText: 'Actions',
}

export { Table }
Loading

0 comments on commit 9def991

Please sign in to comment.