TDMS/web/src/components/custom/DataTable.tsx
Maksim Skobaro c2d19a7724 improved, more featured, fixed
Exceptions and Errors are better
Files structure is better
New ComponentContext.ts
New DataTable.tsx tables.ts
Massive components refactoring
New Group.java
New LoggingRequestFilter.java LoggingSessionListener.java
New NotificationStore.ts SysInfoStore.ts
New reactiveValue.ts ReactiveControls.tsx
New dependencies
And much more
2025-02-07 07:05:15 +03:00

147 lines
4.8 KiB
TypeScript

import {ComponentContext} from "../../utils/ComponentContext";
import {TableDescriptor} from "../../utils/tables";
import {observer} from "mobx-react";
import {action, makeObservable} from "mobx";
import {FormSelect, Pagination, Table} from "react-bootstrap";
export interface DataTableProps<T> {
tableDescriptor: TableDescriptor<T>;
}
@observer
export class DataTable<T> extends ComponentContext<DataTableProps<T>> {
constructor(props: DataTableProps<T>) {
super(props);
makeObservable(this);
}
header() {
return <tr>
{this.props.tableDescriptor.columns.map(column => <th className={'text-center'}
key={column.key}>{column.title}</th>)}
</tr>
}
body() {
const firstColumnKey = this.props.tableDescriptor.columns[0].key;
return this.props.tableDescriptor.data.map(row => {
const rowAny = row as any;
return <tr key={rowAny[firstColumnKey]}>
{
this.props.tableDescriptor.columns.map(column => {
return <td
className={'text-center'}
key={column.key}>
{column.format(rowAny[column.key])}
</td>
})
}
</tr>
});
}
isFirstPage() {
if (typeof this.props.tableDescriptor.page === 'undefined') {
return true;
}
return this.props.tableDescriptor.page === 0;
}
isLastPage() {
if (typeof this.props.tableDescriptor.page === 'undefined' || typeof this.props.tableDescriptor.pageSize === 'undefined') {
return true;
}
return this.props.tableDescriptor.page === (this.props.tableDescriptor.data.length / this.props.tableDescriptor.pageSize);
}
@action.bound
goFirstPage() {
if (typeof this.props.tableDescriptor.page === 'undefined') {
return;
}
this.props.tableDescriptor.page = 0;
}
@action.bound
goLastPage() {
if (typeof this.props.tableDescriptor.page === 'undefined' || typeof this.props.tableDescriptor.pageSize === 'undefined') {
return;
}
this.props.tableDescriptor.page = this.props.tableDescriptor.data.length / this.props.tableDescriptor.pageSize;
}
@action.bound
goNextPage() {
if (typeof this.props.tableDescriptor.page === 'undefined' || typeof this.props.tableDescriptor.pageSize === 'undefined') {
return;
}
this.props.tableDescriptor.page++;
}
@action.bound
goPrevPage() {
if (typeof this.props.tableDescriptor.page === 'undefined') {
return;
}
this.props.tableDescriptor.page--;
}
@action.bound
changePageSize(e: any) {
this.props.tableDescriptor.pageSize = parseInt(e.target.value);
}
footer() {
const table = this.props.tableDescriptor;
if (typeof table.page === 'undefined' || typeof table.pageSize === 'undefined') {
return null;
}
return <tr className={'text-center'}>
<td colSpan={table.columns.length}>
<div className={'d-flex justify-content-between'}>
<div/>
<Pagination className={'mb-0'}>
<Pagination.First onClick={this.goFirstPage} disabled={this.isFirstPage()}/>
<Pagination.Ellipsis disabled={this.isFirstPage()}/>
<Pagination.Prev onClick={this.goPrevPage} disabled={this.isFirstPage()}/>
<Pagination.Item active>{this.props.tableDescriptor.page}</Pagination.Item>
<Pagination.Next onClick={this.goNextPage} disabled={!this.isLastPage()}/>
<Pagination.Ellipsis disabled={!this.isLastPage()}/>
<Pagination.Last onClick={this.goLastPage} disabled={!this.isLastPage()}/>
</Pagination>
<FormSelect className={'w-auto'} onChange={this.changePageSize}>
<option>10</option>
<option>20</option>
<option>50</option>
<option>100</option>
</FormSelect>
</div>
</td>
</tr>
}
render() {
const table = this.props.tableDescriptor;
return <Table hover striped>
<thead>
{this.header()}
</thead>
<tbody>
{this.body()}
</tbody>
{
table.pageable &&
<tfoot>
{this.footer()}
</tfoot>
}
</Table>
}
}