import { Form, Table, Button, Popconfirm } from 'antd' import { EditOutlined, SaveOutlined, PlusOutlined, CloseCircleOutlined, DeleteOutlined } from '@ant-design/icons' import { useState, useEffect, memo, useCallback } from 'react' import { invokeWebApiWrapperAsync } from '@components/factory' import { EditableCell } from './EditableCell' const newRowKeyValue = 'newRow' const actions = [ [['insert'], (data) => [data]], [['insertRange'], (data) => [[data].flat(1)]], [['edit', 'update', 'put'], (data) => data.id && [data.id, data]], [['delete'], (data) => data.id && [data.id]], ] export const makeActionHandler = (action, { idWell, service, setLoader, errorMsg, onComplete }, recordParser, actionName) => service && action && ( (record) => invokeWebApiWrapperAsync( async () => { const addIdWell = (...params) => idWell ? [idWell, ...params] : params if (typeof recordParser === 'function') record = recordParser(record) const actionId = actions.findIndex((elm) => elm[0].includes(action)) const params = actions[actionId]?.[1](record) if (params) await service[action](...addIdWell(...params)) await onComplete?.() }, setLoader, errorMsg, actionName ) ) export const tryAddKeys = (items) => { if (!items?.length || !items[0]) return [] if (items[0].key) return items return items.map((item, index) => ({...item, key: item.key ?? item.id ?? index })) } export const EditableTable = memo(({ columns, dataSource, onChange, // Метод вызывается со всем dataSource с измененными элементами после любого действия onRowAdd, // Метод вызывается с новой добавленной записью. Если метод не определен, то кнопка добавления строки не показывается onRowEdit, // Метод вызывается с новой отредактированной записью. Если метод не поределен, то кнопка редактирования строки не показывается onRowDelete, // Метод вызывается с удаленной записью. Если метод не поределен, то кнопка удаления строки не показывается additionalButtons, buttonsWidth, ...otherTableProps }) => { const [form] = Form.useForm() const [data, setData] = useState(tryAddKeys(dataSource)) const [editingKey, setEditingKey] = useState('') useEffect(() => { setData(tryAddKeys(dataSource)) }, [dataSource]) const isEditing = useCallback((record) => record?.key === editingKey, [editingKey]) const edit = useCallback((record) => { form.setFieldsValue({...record}) setEditingKey(record.key) }, [form]) const cancel = useCallback(() => { if (editingKey === newRowKeyValue) { const newData = [...data] const index = newData.findIndex((item) => newRowKeyValue === item.key) newData.splice(index, 1) setData(newData) } setEditingKey('') }, [data, editingKey]) const addNewRow = useCallback(async () => { let newRow = { ...form.initialValues, key:newRowKeyValue } const newData = [newRow, ...data] setData(newData) edit(newRow) }, [data, edit, form.initialValues]) const save = useCallback(async (record) => { try { const row = await form.validateFields() const newData = [...data] const index = newData.findIndex((item) => record.key === item.key) const item = newData[index] const newItem = { ...item, ...row } newData.splice(index, 1, newItem) if (item.key === newRowKeyValue) item.key = newRowKeyValue + newData.length const isAdding = editingKey === newRowKeyValue setEditingKey('') setData(newData) if (isAdding) try { onRowAdd(newItem) } catch (err) { console.log('callback onRowAdd fault:', err) } else try { onRowEdit(newItem) } catch (err) { console.log('callback onRowEdit fault:', err) } try { onChange?.(newData) } catch (err) { console.log('callback onChange fault:', err) } } catch (errInfo) { console.log('Validate Failed:', errInfo) } }, [data, editingKey, form, onChange, onRowAdd, onRowEdit]) const deleteRow = useCallback((record) => { const newData = [...data] const index = newData.findIndex((item) => record.key === item.key) newData.splice(index, 1) setData(newData) onRowDelete(record) onChange?.(newData) }, [data, onChange, onRowDelete]) const operationColumn = { width: buttonsWidth ?? 82, title: !!onRowAdd && (