diff --git a/src/components/EditableTable.jsx b/src/components/EditableTable.jsx new file mode 100644 index 0000000..24b2ace --- /dev/null +++ b/src/components/EditableTable.jsx @@ -0,0 +1,140 @@ +import { Form, Input, Popconfirm, Typography, Table } from "antd" +import { useState } from "react"; + +const EditableCell = ({ + editing, + record, + dataIndex, + input, + isRequired, + title, + formItemClass, + formItemRules, + children, +}) => { + + const inputNode = input ?? + const rules = formItemRules ?? [{ + required: isRequired, + message: `Please Input ${title}!`, + }] + + const editor = + {inputNode} + + + return ( + {editing ? editor: children} + ) +} + +export const EditableTable = ({columns, dataSource, onUpdateData: onChange, ...otherTableProps}) => { + const [form] = Form.useForm() + const [editingKey, setEditingKey] = useState('') + + const isEditing = (record) => record.key === editingKey + + const edit = (record) => { + form.setFieldsValue({...record}) + setEditingKey(record.key) + } + + const cancel = () => { + setEditingKey('') + } + + const save = async (key) => { + try { + const row = await form.validateFields() + const newData = [...dataSource] + const index = newData.findIndex((item) => key === item.key) + + if (index > -1) { + const item = newData[index] + newData.splice(index, 1, { ...item, ...row }) + } else { + newData.push(row) + } + + setEditingKey('') + if(onChange) + onChange(newData) + else + console.error(`EditableTable.onChange doesn't connected`) + } catch (errInfo) { + console.log('Validate Failed:', errInfo) + } + } + + const operationColumn = { + title: '', + dataIndex: 'operation', + render: (_, record) => { + const editable = isEditing(record) + return editable ? ( + + save(record.key)} + style={{ + marginRight: 8, + }} + > + Save + + + Cancel + + + ) : ( + edit(record)}> + Edit + + ) + }, + } + + const handleColumn = (col) => { + if (col.children) + col.children = col.children.map(handleColumn) + + if (!col.editable) + return col + + return { + ...col, + onCell: (record) => ({ + editing: isEditing(record), + record, + dataIndex: col.dataIndex ?? col.key, + input: col.input, + isRequired: col.isRequired, + title: col.title, + dataType: col.dataType, + formItemClass: col.formItemClass, + formItemRules: col.formItemRules, + }), + } + } + + const mergedColumns = [...columns.map(handleColumn), operationColumn] + + return ( +
+ + + ) +} \ No newline at end of file