imeeting/components/ListTable/ListTable.tsx

118 lines
3.4 KiB
TypeScript

import { Table } from "antd";
import type { ColumnsType, TablePaginationConfig, TableRowSelection } from "antd/es/table";
import "./ListTable.css";
export type ListTableProps<T extends Record<string, any>> = {
columns: ColumnsType<T>;
dataSource: T[];
rowKey?: string;
selectedRowKeys?: React.Key[];
onSelectionChange?: (keys: React.Key[]) => void;
isAllPagesSelected?: boolean;
totalCount?: number;
onSelectAllPages?: () => void;
onClearSelection?: () => void;
pagination?: TablePaginationConfig | false;
scroll?: { x?: number | true | string };
onRowClick?: (record: T) => void;
selectedRow?: T | null;
loading?: boolean;
className?: string;
};
function ListTable<T extends Record<string, any>>({
columns,
dataSource,
rowKey = "id",
selectedRowKeys = [],
onSelectionChange,
isAllPagesSelected = false,
totalCount,
onSelectAllPages,
onClearSelection,
pagination = {
pageSize: 10,
showSizeChanger: true,
showQuickJumper: true,
},
scroll = { x: 1200 },
onRowClick,
selectedRow,
loading = false,
className = "",
}: ListTableProps<T>) {
const rowSelection: TableRowSelection<T> | undefined = onSelectionChange
? {
selectedRowKeys,
onChange: (newSelectedRowKeys) => {
onSelectionChange?.(newSelectedRowKeys);
},
getCheckboxProps: () => ({
disabled: isAllPagesSelected,
}),
}
: undefined;
const mergedPagination =
pagination === false
? false
: {
...pagination,
showTotal: (total: number) => (
<div className="table-selection-info">
{isAllPagesSelected ? (
<>
<span className="selection-count">
<span className="count-highlight">{totalCount || total}</span>
</span>
{onClearSelection && (
<a onClick={onClearSelection} className="selection-action">
</a>
)}
</>
) : selectedRowKeys.length > 0 ? (
<>
<span className="selection-count">
<span className="count-highlight">{selectedRowKeys.length}</span>
</span>
{onSelectAllPages && selectedRowKeys.length < (totalCount || total) && (
<a onClick={onSelectAllPages} className="selection-action">
{totalCount || total}
</a>
)}
{onClearSelection && (
<a onClick={onClearSelection} className="selection-action">
</a>
)}
</>
) : (
<span className="selection-count"> 0 </span>
)}
</div>
),
};
return (
<div className={`list-table-container ${className}`}>
<Table
size="middle"
rowSelection={rowSelection}
columns={columns}
dataSource={dataSource}
rowKey={rowKey}
pagination={mergedPagination}
scroll={scroll}
loading={loading}
onRow={(record) => ({
onClick: () => onRowClick?.(record),
className: selectedRow?.[rowKey] === record[rowKey] ? "row-selected" : "",
})}
/>
</div>
);
}
export default ListTable;