I am using antd to create a table with filter feature,
but I got a problem, I want to custom filter search of antd to call api,
antd table
How can I do that with react and antd,
Here is my code
const columns: ColumnsType<Product> = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: (name, record) => (
<div className="flex items-center">
<Avatar src={record.avatar}>{name[0].toUpperCase()}</Avatar>
<span style={{ marginLeft: 10 }} className="whitespace-nowrap">
<a title="View & Edit" href={'/product/' + record.id}>
{name}
</a>
</span>
</div>
),
},
{
title: 'About',
dataIndex: 'about',
key: 'about',
render: (about: string) => <p className="text-ellipsis line-clamp-2">{about}</p>,
width: 400,
},
{
title: 'Categories',
dataIndex: 'categories',
key: 'categories',
filterSearch: true,
filters: categories!.map((category: Category) => ({ text: category.name, value: category.id })),
render: (categories: any) => {
console.log(categories);
return '-';
},
// width: 400,
},
{ title: 'Addresses', dataIndex: 'contract_addresses', key: 'address', render: addresses => addresses?.[0] },
];
To filter the table, I usually provide a function that filters the data before it is passed to the table (In my example the function getData. This function can also be used to adjust the filter accordingly. Here is an example, which also consists of a Search-Input to modify the search:
const CustomersTable = (props: any) => {
const [searchText, setSearchText] = useState<string | undefined>(undefined);
const [customers, setCustomers] = useState<ICustomer[]>([]);
const getData = (
sourceData: Array<ICustomer>,
searchText: string | undefined
) => {
if (!searchText) {
return sourceData;
}
return sourceData.filter((item) => {
const comparisonString = `${item.firstname.toLowerCase()}${item.familyname.toLowerCase()}`;
//here you can provide a more sophisticared search
return comparisonString.includes(searchText.toLowerCase());
});
};
const columns = [
{
title: "Vorname",
dataIndex: "firstname",
key: "firstname",
sorter: (a: ICustomer, b: ICustomer) => {
if (a.firstname.toLowerCase() > b.firstname.toLowerCase()) {
return -1;
} else if (a.firstname.toLowerCase() < b.firstname.toLowerCase()) {
return 1;
} else {
return 0;
}
},
},
{
title: "Nachname",
dataIndex: "familyname",
key: "familyname",
},
];
return (
<>
<Search
placeholder="Vorname, Nachname"
value={searchText}
onChange={(e) => {
setSearchText(e.target.value);
}}
/>
<Table
columns={columns}
dataSource={getData(customers, searchText)}
/>
</>
);
};
Related
I am trying to implement crud functionalities in Ant design table. I observed that the delete and edit functionalities only works on the instance when I perform the operations on initial render, but after reloading the component, the table returns back to its initial state and the operations don't affect the database in any way.
I see this error on my console
Type '{ title: string; dataIndex: string; key: string; align: string; editable: boolean;
render?: undefined; }' is not assignable to type 'ColumnType<any>'.
Types of property 'align' are incompatible.
Type 'string' is not assignable to type 'AlignType'.
These are the codes below, I hope to break them down in code blocks so they can be understandable
imports
import React, { useState, useEffect } from 'react';
import { Table, Popconfirm, Button, Space, Input, Form } from 'antd';
import { isEmpty } from 'lodash';
api
const apiUrl = 'api/terminals';
useState and useEffect codes
const [gridData, setGridData] = useState([]);
const [loader, setLoader] = useState(false);
const [editingKey, setEditingKey] = useState('');
const [editRow, setEditRow] = useState(false);
const [form] = Form.useForm();
useEffect(() => {
loadData();
}, []);
const loadData = async () => {
setLoader(true);
const response = await axios.get(apiUrl);
setGridData(response.data);
setLoader(false);
};
modifiedData codes
const modifiedData = gridData.map(({ ...item }) => ({
...item,
key: item.id,
}));
const save = async key => {
try {
const row = await form.validateFields();
const newData = [...modifiedData];
const index = newData.findIndex(item => key === item.key);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, { ...item, ...row });
setGridData(newData);
setEditingKey('');
}
} catch (error) {
console.warn('Error', error);
}
};
edit and cancel function code block
const edit = record => {
form.setFieldsValue({
name: '',
stock: '',
stockLevelDate: '',
tankThreatLevel: '',
tankThreatLevelColor: '',
tankTopPosition: '',
tankTopPositionColor: '',
lowPumpable: '',
lowPumpableColor: '',
tankCapacity: '',
...record,
});
setEditingKey(record.key);
};
const cancel = () => {
setEditingKey('');
};
editableCell function block
const EditableCell = ({ editing, dataIndex, title, record, children, ...restProps }) =>
{
const input = <Input />;
return (
<td {...restProps}>
{editing ? (
<Form.Item
name={dataIndex}
style={{ margin: 0 }}
rules={[
{
required: true,
message: `Please input ${title}`,
},
]}
>
{input}
</Form.Item>
) : (
children
)}
</td>
);
};
editing code block
const isEditing = record => {
return record.key === editingKey;
};
columns block
const columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
},
{
title: 'Name' as string,
dataIndex: 'name',
key: 'name',
align: 'center',
editable: true,
},
{
title: 'Stock',
dataIndex: 'stock',
key: 'stock',
align: 'center',
editable: true,
},
{
title: 'Stock Level Date',
dataIndex: 'stockLevelDate',
key: 'stockLevelDate',
align: 'center',
editable: true,
},
{
title: 'Tank Threat Level',
dataIndex: 'tankThreatLevel',
key: 'tankThreatLevel',
align: 'center',
editable: true,
},
{
title: 'Tank Threat Level Color',
dataIndex: 'tankThreatLevelColor',
key: 'tankThreatLevelColor',
align: 'center',
editable: true,
},
{
title: 'Tank Top Position',
dataIndex: 'tankTopPosition',
key: 'tankTopPosition',
align: 'center',
editable: true,
},
{
title: 'Tank Top Position Color',
dataIndex: 'tankTopPositionColor',
key: 'tankTopPositionColor',
align: 'center',
editable: true,
},
{
title: 'Low Pumpable',
dataIndex: 'lowPumpable',
key: 'lowPumpable',
align: 'center',
editable: true,
},
{
title: 'Low Pumpable Color',
dataIndex: 'lowPumpableColor',
key: 'lowPumpableColor',
align: 'center',
editable: true,
},
{
title: 'Tank Capacity',
dataIndex: 'tankCapacity',
key: 'tankCapacity',
align: 'center',
editable: true,
},
{
title: 'Actions',
dataIndex: 'actions',
key: 'actions',
align: 'center',
render: (_, record) => {
const editable = isEditing(record);
return modifiedData.length >= 1 ? (
<Space>
<Popconfirm title="Sure to delete?" onConfirm={() => handleDelete(record)}>
<Button type="primary" disabled={editable} danger>
Delete
</Button>
</Popconfirm>
{editable ? (
<span>
<Space size="middle">
<Button onClick={e => save(record.key)} type="primary" style={{ marginRight: 8
}}>
{' '}
Save
</Button>
<Popconfirm title="Sure to cancel?" onConfirm={cancel}>
<Button>Cancel</Button>
</Popconfirm>
</Space>
</span>
) : (
<Button onClick={() => edit(record)} type="primary">
Edit
</Button>
)}
</Space>
) : null;
},
},
];
mergedCoulumns block
const mergedColumns = columns.map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: record => ({
record,
dataIndex: col.dataIndex,
title: col.title,
editing: isEditing(record),
}),
};
});
handleDelete code block
const handleDelete = value => {
const dataSource = [...modifiedData];
const filteredData = dataSource.filter(item => item.id !== value.id);
setGridData(filteredData);
};
return jsx
<>
<div>
<h2>Terminals</h2>
<Link to={`${match.url}/new`} className="btn btn-primary jh-create-entity" id="jh
-create-
entity" data-cy="entityCreateButton">
<FontAwesomeIcon icon="plus" />
Add Terminal
</Link>
<hr color="red" />
<Form form={form} component={false}>
<Table
components={{
body: {
cell: EditableCell,
},
}}
columns={mergedColumns}
dataSource={modifiedData}
bordered
loading={loader}
/>
</Form>
</div>
</>
Thanks in anticipation
**Here is the cart imports and state
const Cart = ({ cart, setActiveTab, removeFromCart, updateQuantity }) => {
const [selectedRows , setSelectedRows] = useState([]);
const [toggleCleared, setToggleCleared] = useState(false);
const [products, setProducts] = useState(cart.products) }
const columns = [
{
name: 'Product Name',
selector: 'name',
sortable: true,
},
{
name: 'Product Price',
selector: 'price',
sortable: true,
right: true,
},
{
name: 'Product Quantity',
selector: 'quantity',
sortable: true,
right: true,
cell: row => <Fragment><input type="number" className="form-control" value={row.quantity} onChange = {(e)=>updateQuantity( row.id,strong text e.target.value)}/></Fragment>
},
{
name: 'Subtotal',
selector: 'quantity',
sortable: true,
right: true,
cell: row => <Fragment>{row.quantity * row.price}</Fragment>
},
{
name: 'Actions',
selector: 'quantity',
sortable: true,
right: true,
cell: row => <Fragment><i className="fa fa-trash" aria-hidden="true" onClick = {(e)=>removeFromCart(row.id)}></i></Fragment>
},
];
const contextActions = useMemo(() => {
const handleDelete = () => {
selectedRows.forEach(item=>{
console.log(item, 'item')
removeFromCart(products, products.indexOf(item))
});
setProducts(products);
setToggleCleared(!toggleCleared);
console.log('handleDelete', products)
};
return <i className="fa fa-trash" key="delete" onClick={handleDelete} style={{ backgroundColor: 'red' }} ></i>;
});
This code sets the selected rows when we select rows
function rowSelection (rows) =>{
setSelectedRows(rows.selectedRows);
}
return ( <DataTable
title="Cart Products"
columns={columns}
data={products}
selectableRows
onSelectedRowsChange={rowSelection}
clearSelectedRows={toggleCleared}
contextActions={contextActions} />
)
**here is the my cart component which works fine but it does not updates itself when the redux state changes.. i can see the redux state in console that it changes perfectly but datatable does not rerenders
const [products, setProducts] = useState(cart.products) } this will only works on initial rendering ( called initial state).useState will not call once the render is completed. so just pass the cart.products in to the datatable
function rowSelection (rows) =>{
setSelectedRows(rows.selectedRows);
}
return ( <DataTable
title="Cart Products"
columns={columns}
data={cart.products}
selectableRows
onSelectedRowsChange={rowSelection}
clearSelectedRows={toggleCleared}
contextActions={contextActions} /> )
I am using react-table plugin, and my cells keep re-rendering while I am changing the applied searching filter even though their values aren't changed.
As seen in the video, name and debt TDs keep updating, even though their values are static.
https://i.imgur.com/2KkNs9f.mp4
I imagine, that may impact performance on larger tables.
Is there any fix? Or am I doing anything wrong?
Thanks.
Edit:
Code has been requested. Not much to show, basically everything done as in documentation.
Rendering part:
render(){
const columns = [
{
Header: "Name",
accessor: "name",
className: css.cell,
headerClassName: css.cell,
filterMethod: (filter, row) => {
return row[filter.id]
.toLowerCase()
.includes(filter.value.toLowerCase());
},
Cell: props => {
return <span>{props.value}</span>;
}
},
{
Header: "Tc",
accessor: d => {
const date = d.lastChange;
if (date.length) {
const s = date.split(" ");
const s2 = s[0].split("/");
const mdy = [s2[1], s2[0], s2[2]].join("/");
const his = s[1];
return Date.parse(mdy + " " + his);
}
return "";
},
id: "lastChange",
Cell: props => {
return <ArrowTime lastChange={props.value}></ArrowTime>;
},
headerClassName: css.cell,
className: css.cell
},
{
Header: "Debt",
accessor: d => Number(d.lastDebt),
id: "lastDebt",
headerClassName: css.cell,
className: css.cell,
Cell: props => {
return <span className="number">{props.value}</span>;
},
getProps: (state, rowInfo, column) => {
return {
style: {
background: rowInfo ? this.getColor(rowInfo.row.lastDebt) : null
}
};
}
}
];
return (
<ReactTable
data={this.props.table}
columns={columns}
minRows={0}
showPagination={false}
NoDataComponent={CustomNoDataComponent}
className={css.table}
resizable={false}
filtered={[{ id: "name", value: this.props.filter }]}
getTrProps={(state, rowInfo) => {
return {
className: rowInfo ? css.subRow : ""
};
}}
getTrGroupProps={(state, rowInfo) => {
return {
className: rowInfo ? css.row : ""
};
}}
getTbodyProps={props => {
return {
className: props ? css.tbody : ""
};
}}
getTheadProps={props => {
return {
className: props ? css.thead : ""
};
}}
defaultSorted={[
{
id: "lastDebt",
desc: true
}
]}
/>
);
}
Based on ANTD's Table example: https://ant.design/components/table/#components-table-demo-edit-cell, I would like to replicate this, with the addition of having the ability to add/delete new columns. The sample from the link above only illustrates how to add new rows.
Here's the code from the sample:
import { Table, Input, Button, Popconfirm, Form } from 'antd';
const FormItem = Form.Item;
const EditableContext = React.createContext();
const EditableRow = ({ form, index, ...props }) => (
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
);
const EditableFormRow = Form.create()(EditableRow);
class EditableCell extends React.Component {
state = {
editing: false,
}
componentDidMount() {
if (this.props.editable) {
document.addEventListener('click', this.handleClickOutside, true);
}
}
componentWillUnmount() {
if (this.props.editable) {
document.removeEventListener('click', this.handleClickOutside, true);
}
}
toggleEdit = () => {
const editing = !this.state.editing;
this.setState({ editing }, () => {
if (editing) {
this.input.focus();
}
});
}
handleClickOutside = (e) => {
const { editing } = this.state;
if (editing && this.cell !== e.target && !this.cell.contains(e.target)) {
this.save();
}
}
save = () => {
const { record, handleSave } = this.props;
this.form.validateFields((error, values) => {
if (error) {
return;
}
this.toggleEdit();
handleSave({ ...record, ...values });
});
}
render() {
const { editing } = this.state;
const {
editable,
dataIndex,
title,
record,
index,
handleSave,
...restProps
} = this.props;
return (
<td ref={node => (this.cell = node)} {...restProps}>
{editable ? (
<EditableContext.Consumer>
{(form) => {
this.form = form;
return (
editing ? (
<FormItem style={{ margin: 0 }}>
{form.getFieldDecorator(dataIndex, {
rules: [{
required: true,
message: `${title} is required.`,
}],
initialValue: record[dataIndex],
})(
<Input
ref={node => (this.input = node)}
onPressEnter={this.save}
/>
)}
</FormItem>
) : (
<div
className="editable-cell-value-wrap"
style={{ paddingRight: 24 }}
onClick={this.toggleEdit}
>
{restProps.children}
</div>
)
);
}}
</EditableContext.Consumer>
) : restProps.children}
</td>
);
}
}
class EditableTable extends React.Component {
constructor(props) {
super(props);
this.columns = [{
title: 'name',
dataIndex: 'name',
width: '30%',
editable: true,
}, {
title: 'age',
dataIndex: 'age',
}, {
title: 'address',
dataIndex: 'address',
}, {
title: 'operation',
dataIndex: 'operation',
render: (text, record) => (
this.state.dataSource.length >= 1
? (
<Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}>
Delete
</Popconfirm>
) : null
),
}];
this.state = {
dataSource: [{
key: '0',
name: 'Edward King 0',
age: '32',
address: 'London, Park Lane no. 0',
}, {
key: '1',
name: 'Edward King 1',
age: '32',
address: 'London, Park Lane no. 1',
}],
count: 2,
};
}
handleDelete = (key) => {
const dataSource = [...this.state.dataSource];
this.setState({ dataSource: dataSource.filter(item => item.key !== key) });
}
handleAdd = () => {
const { count, dataSource } = this.state;
const newData = {
key: count,
name: `Edward King ${count}`,
age: 32,
address: `London, Park Lane no. ${count}`,
};
this.setState({
dataSource: [...dataSource, newData],
count: count + 1,
});
}
handleSave = (row) => {
const newData = [...this.state.dataSource];
const index = newData.findIndex(item => row.key === item.key);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
});
this.setState({ dataSource: newData });
}
render() {
const { dataSource } = this.state;
const components = {
body: {
row: EditableFormRow,
cell: EditableCell,
},
};
const columns = this.columns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: record => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave: this.handleSave,
}),
};
});
return (
<div>
<Button onClick={this.handleAdd} type="primary" style={{ marginBottom: 16 }}>
Add a row
</Button>
<Table
components={components}
rowClassName={() => 'editable-row'}
bordered
dataSource={dataSource}
columns={columns}
/>
</div>
);
}
}
ReactDOM.render(<EditableTable />, mountNode);
You can make your columns array a part of the state and update it through setState.
Here is a working codepen: https://codepen.io/gges5110/pen/GLPjYr?editors=0010
// State
this.state = {
dataSource: [{
key: '0',
name: 'Edward King 0',
age: '32',
address: 'London, Park Lane no. 0',
}, {
key: '1',
name: 'Edward King 1',
age: '32',
address: 'London, Park Lane no. 1',
}],
columns: [{
title: 'name',
dataIndex: 'name',
width: '30%',
editable: true,
}, {
title: 'age',
dataIndex: 'age',
}]
};
// Event to add new column
handleAddColumn = () => {
const { columns } = this.state;
const newColumn = {
title: 'age',
dataIndex: 'age',
};
this.setState({
columns: [...columns, newColumn]
});
}
// Render method
render() {
const { dataSource, columns } = this.state;
return (
<Table
dataSource={dataSource}
columns={columns}
/>
);
}
I have the following table in Ant Design. The sort and filter icons in Ant Design. The icons aren't showing up, although if I hover over the column header, I can see the "sort" and "filter" text pop up, and the actual sort and filter functionality works.
In my parent component I am importing the CSS
App.css
#import "~antd/dist/antd.css";
App.js
import './App.css';
Assets.js
/* eslint-disable no-undef */
/*
From https://ant.design/components/table/ (Dynamic Settings example)
*/
import React, { Component } from 'react';
import Title from './Title';
import { Table, Icon, Switch, Radio, Form, Divider } from 'antd';
const FormItem = Form.Item;
/* const data = [];
for (let i = 1; i <= 10; i++) {
data.push({
key: i,
name: 'John Brown',
age: `${i}2`,
address: `New York No. ${i} Lake Park`,
description: `My name is John Brown, I am ${i}2 years old, living in New York No. ${i} Lake Park.`
});
} */
const expandedRowRender = record => <p>{record.description}</p>;
const title = () => 'Assets';
const showHeader = true;
const footer = () => 'Here is footer';
const scroll = { y: 240 };
const pagination = { position: 'bottom' };
// TODO: Delete this after swapping in the table
/* const renderAssets = (data, handleAssetClick) => {
console.log('renderAssets data', data);
const assetsToRender = data.map(asset => {
const assetDiv = (
<div style={{ display: 'block' }} onClick={handleAssetClick} value={asset.id} key={asset.id}>
{asset.name}
</div>
);
return assetDiv;
});
console.log('Assets assetsToRender', assetsToRender);
return assetsToRender;
}; */
const getAssets = data => {
console.log('getAssets data', data);
let assets = [];
assets = data.map(asset => {
//console.log(asset);
return {
key: asset.id,
id: asset.id,
name: asset.name,
type: asset.properties.class,
substation: asset.properties.substation,
feeder: asset.properties.feeder,
status: asset.properties.service_status,
vulnerability: asset.properties.peak_vulnerability
};
});
console.log('Assets', assets);
return assets;
};
class Assets extends Component {
constructor(props) {
super(props);
console.log('Assets data', this.props.data, 'handleAssetClick', this.props.handleAssetClick);
this.state = {
bordered: true,
loading: false,
pagination,
size: 'default',
//expandedRowRender,
title,
showHeader,
//footer,
// rowSelection: {},
scroll: undefined,
hasData: true
};
}
componentDidMount() {
if (!this.props.data || !this.props.data.length || this.props.data.length === 0) {
return null;
}
}
handleToggle = prop => {
return enable => {
this.setState({ [prop]: enable });
};
};
handleSizeChange = e => {
this.setState({ size: e.target.value });
};
handleExpandChange = enable => {
this.setState({ expandedRowRender: enable ? expandedRowRender : undefined });
};
handleTitleChange = enable => {
this.setState({ title: enable ? title : undefined });
};
handleHeaderChange = enable => {
this.setState({ showHeader: enable ? showHeader : false });
};
handleFooterChange = enable => {
this.setState({ footer: enable ? footer : undefined });
};
handleRowSelectionChange = enable => {
this.setState({ rowSelection: enable ? {} : undefined });
};
handleScollChange = enable => {
this.setState({ scroll: enable ? scroll : undefined });
};
handleDataChange = hasData => {
this.setState({ hasData });
};
handlePaginationChange = e => {
const { value } = e.target;
this.setState({
pagination: value === 'none' ? false : { position: value }
});
};
stringSorter(a, b) {
let a2 = '',
b2 = '';
if (a) {
a2 = a;
}
if (b) {
b2 = b;
}
return a2.localeCompare(b2);
}
stringFilterer(value, record, property) {
let recStatus = '';
if (record[property]) {
recStatus = record[property];
}
return recStatus.indexOf(value) === 0;
}
columns = [
{
title: 'ID',
dataIndex: 'id',
key: 'id',
//width: 50
width: '10%',
sorter: (a, b) => a.id - b.id
},
{
title: 'Name',
dataIndex: 'name',
key: 'name',
//width: 200
width: '15%',
sorter: (a, b) => this.stringSorter(a.name, b.name)
},
{
title: 'Type',
dataIndex: 'type',
key: 'type',
//width: 80
width: '12%',
sorter: (a, b) => this.stringSorter(a.type, b.type),
filters: [
{
text: 'meter',
value: 'meter'
},
{
text: 'climate',
value: 'climate'
},
{
text: 'pole',
value: 'pole'
},
{
text: 'overhead_line',
value: 'overhead_line'
}
],
onFilter: (value, record) => this.stringFilterer(value, record, 'type')
},
{
title: 'Substation',
dataIndex: 'substation',
key: 'substation',
//width: 150
width: '16%',
sorter: (a, b) => this.stringSorter(a.substation, b.substation)
// TODO: Add Filtering by Substation
},
{
title: 'Feeder',
dataIndex: 'feeder',
key: 'feeder',
//width: 100
width: '16%',
sorter: (a, b) => this.stringSorter(a.feeder, b.feeder)
// TODO: Add Filtering by Feeder
},
{
title: 'Status',
dataIndex: 'status',
key: 'status',
//width: 120
width: '18%',
sorter: (a, b) => this.stringSorter(a.status, b.status),
filters: [
{
text: 'IN_SERVICE',
value: 'IN_SERVICE'
},
{
text: 'OUT_OF_SERVICE',
value: 'OUT_OF_SERVICE'
}
],
onFilter: (value, record) => this.stringFilterer(value, record, 'status')
},
{
title: 'Peak\
Vulnerability\
(Pole Stress)',
key: 'vulnerability',
dataIndex: 'vulnerability',
sorter: (a, b) => this.stringSorter(a.vulnerability, b.vulnerability)
//width: 120
}
];
render() {
const { data, handleAssetClick, readyToLoad } = this.props;
{
/* <div style={{ display: 'inline-block', textAlign: 'left' }}>
<Title text="Assets" />
<div>{renderAssets(data, handleAssetClick)}</div>
</div> */
}
return (
<div>
{/* <div className="components-table-demo-control-bar">
<Form layout="inline">
<FormItem label="Bordered">
<Switch checked={this.state.bordered} onChange={this.handleToggle('bordered')} />
</FormItem>
<FormItem label="loading">
<Switch checked={this.state.loading} onChange={this.handleToggle('loading')} />
</FormItem>
<FormItem label="Title">
<Switch checked={!!this.state.title} onChange={this.handleTitleChange} />
</FormItem>
<FormItem label="Column Header">
<Switch checked={!!this.state.showHeader} onChange={this.handleHeaderChange} />
</FormItem>
<FormItem label="Footer">
<Switch checked={!!this.state.footer} onChange={this.handleFooterChange} />
</FormItem>
<FormItem label="Expandable">
<Switch checked={!!this.state.expandedRowRender} onChange={this.handleExpandChange} />
</FormItem>
<FormItem label="Checkbox">
<Switch
checked={!!this.state.rowSelection}
onChange={this.handleRowSelectionChange}
/>
</FormItem>
<FormItem label="Fixed Header">
<Switch checked={!!this.state.scroll} onChange={this.handleScollChange} />
</FormItem>
<FormItem label="Has Data">
<Switch checked={!!this.state.hasData} onChange={this.handleDataChange} />
</FormItem>
<FormItem label="Size">
<Radio.Group size="default" value={this.state.size} onChange={this.handleSizeChange}>
<Radio.Button value="default">Default</Radio.Button>
<Radio.Button value="middle">Middle</Radio.Button>
<Radio.Button value="small">Small</Radio.Button>
</Radio.Group>
</FormItem>
<FormItem label="Pagination">
<Radio.Group
value={this.state.pagination ? this.state.pagination.position : 'none'}
onChange={this.handlePaginationChange}
>
<Radio.Button value="top">Top</Radio.Button>
<Radio.Button value="bottom">Bottom</Radio.Button>
<Radio.Button value="both">Both</Radio.Button>
<Radio.Button value="none">None</Radio.Button>
</Radio.Group>
</FormItem>
</Form>
</div> */}
<Table
size="small"
onRow={record => {
return {
onClick: e => {
this.props.handleAssetClick(e);
} // click row
//onMouseEnter: () => {}, // mouse enter row
};
}}
{...this.state}
columns={this.columns}
dataSource={this.state.hasData ? getAssets(data) : null}
/>
</div>
);
}
}
export default Assets;
This turned out to be a CSS problem. I had padding around all of the SVGs, which made hid these small icons.