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
147 lines
4.8 KiB
TypeScript
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>
|
|
}
|
|
} |