-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtable.tsx
More file actions
123 lines (114 loc) · 4.42 KB
/
table.tsx
File metadata and controls
123 lines (114 loc) · 4.42 KB
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
import React, { useCallback } from 'react';
import { Table as SemanticTable } from 'semantic-ui-react';
import { map } from 'lodash-es';
import { useRelatableStateContext } from '../states';
import arrayHasItems from '../utils/array-has-items';
import { columnHasActions } from '../utils/column-actions';
import getSemanticTableProps from '../utils/get-semantic-table-props';
import isLastIndex from '../utils/is-last-index';
import getRowNumber from '../utils/get-row-number';
import ColumnActions from './column-actions';
import { BodyRow } from './renderers';
import RowActions from './renderers/row-actions';
export interface ITableProps {
// used for rendering loading animation and empty rows
loading?: boolean;
expectedRowCount?: number;
headless?: boolean;
// semantic ui react props https://react.semantic-ui.com/collections/table/
attached?: boolean | string;
basic?: boolean | string;
className?: string;
collapsing?: boolean;
color?: string;
compact?: boolean | string;
definition?: boolean;
fixed?: boolean;
inverted?: boolean;
padded?: boolean | string;
singleLine?: boolean;
size?: string;
striped?: boolean;
structured?: boolean;
textAlign?: string;
verticalAlign?: string;
}
export default function Table({ loading, expectedRowCount, headless, ...rest }: ITableProps): JSX.Element {
const {
getTableProps,
headerGroups,
state: {
pageIndex = 0,
pageSize = 1,
},
_rowsToUse: rows, // @todo: handle this more gracefully inside addOns
prepareRow,
availableTableActions,
onCustomSelectionChange,
} = useRelatableStateContext();
const { className = '', ...semanticTableProps } = getSemanticTableProps(rest);
const onSelectAllClick = useCallback(
(select: boolean) => {
onCustomSelectionChange!(rows, select);
},
[onCustomSelectionChange, rows],
);
return (
<SemanticTable {...getTableProps()} {...semanticTableProps} className={`relatable__table ${className}`}>
{!headless && <SemanticTable.Header>
{map(headerGroups, (headerGroup, index: number) => (
<SemanticTable.Row
{...headerGroup.getHeaderGroupProps()}
className="relatable__table-row relatable__table-header-row">
<SemanticTable.HeaderCell
className="relatable__table-cell relatable__table-header-cell relatable__table-header-actions-cell"
collapsing>
{isLastIndex(headerGroups, index) &&
<RowActions rows={rows} onSelectClick={onCustomSelectionChange && onSelectAllClick}/>}
</SemanticTable.HeaderCell>
{map(headerGroup.headers, (column: any) => {
const headerProps = column.getHeaderProps();
const hasActions = isLastIndex(headerGroups, index) && columnHasActions(column, availableTableActions);
if (column.colSpan === 0) return null;
return hasActions
? <ColumnActions
column={column}
{...headerProps}/>
: <SemanticTable.HeaderCell
{...headerProps}
colSpan={column.colSpan !== undefined ? column.colSpan : headerProps.colSpan}
className="relatable__table-cell relatable__table-header-cell">
{column.render('Header')}
</SemanticTable.HeaderCell>;
},
)}
</SemanticTable.Row>
))}
</SemanticTable.Header>}
<SemanticTable.Body>
{map(rows, (row, index: number) => {
prepareRow(row);
return (
<BodyRow
row={row}
rowNumber={getRowNumber(index, pageIndex, pageSize)}
loading={loading}
{...row.getRowProps()}
/>
);
})}
{/* render empty rows when passed expectedRowCount and no data */}
{!arrayHasItems(rows) && loading && expectedRowCount
? map(Array(expectedRowCount), (_, index) => (
<SemanticTable.Row key={`empty-row-${index}`} className="relatable__table-row relatable__table-body-row">
<SemanticTable.Cell className="relatable__table-cell relatable__table-body-cell" colSpan="100%">
<div className="relatable__table-body-cell-loader"/>
</SemanticTable.Cell>
</SemanticTable.Row>
))
: null
}
</SemanticTable.Body>
</SemanticTable>
);
}