packages/form-render/src/widgets/listTable/index.tsx (197 lines of code) (raw):

import React from 'react'; import { Table, Form, Space, Popconfirm, Button, Divider, Tooltip } from 'antd'; import type { FormListFieldData, TableColumnsType } from 'antd'; import { ArrowDownOutlined, ArrowUpOutlined, PlusOutlined, CloseOutlined, CopyOutlined, InfoCircleOutlined } from '@ant-design/icons'; import classnames from 'classnames'; import TableCell from './tableCell'; import FButton from '../components/FButton'; import sortProperties from '../../models/sortProperties'; import './index.less'; interface ListTableProps { fields: FormListFieldData[]; schema: any; delConfirmProps: any; renderCore: any; rootPath: any; /* * 没有数据时是否隐藏表格 */ hideEmptyTable?: boolean; [key: string]: any; }; const getTooltip = (tooltip: any) => { if (!tooltip) { return; } if (typeof tooltip === 'string') { return { title: <span dangerouslySetInnerHTML={{ __html: tooltip }} /> }; } return { ...tooltip, title: <span dangerouslySetInnerHTML={{ __html: tooltip.title }} />, }; }; const TableList: React.FC<ListTableProps> = (props) => { const { form, schema, fields, rootPath, renderCore, readOnly, operateBtnType, addBtnProps, delConfirmProps, copyBtnProps, deleteBtnProps, moveUpBtnProps, moveDownBtnProps, actionColumnProps, pagination, hideDelete, hideCopy, hideMove, hideAdd, hideOperate, hideEmptyTable, addItem, copyItem, moveItem, removeItem, configContext, validatePopover, ...retProps } = props; const { globalConfig } = configContext; const islidatePopover = validatePopover ?? globalConfig?.listValidatePopover ?? true; const { colHeaderText, ...otherActionColumnProps } = actionColumnProps; const itemSchema = schema?.items?.properties || {}; const paginationConfig = { size: 'small', hideOnSinglePage: true, ...pagination, }; const handleCopy = (name: number) => { const value = form.getFieldValue(rootPath.concat(name)); copyItem(value, name); }; const columns: any = sortProperties(Object.entries(itemSchema)).map(([dataIndex, item]) => { const { required, title, width, tooltip, columnHidden } = item; if (columnHidden) { return null; } const tooltipProps = getTooltip(tooltip); return { dataIndex, width, title: ( <> {required && <span style={{ color: 'red', marginRight: '3px' }}>*</span>} <span>{title}</span> {tooltipProps && ( <Tooltip placement='top' {...tooltipProps}> <InfoCircleOutlined style={{ marginLeft: 6 }} /> </Tooltip> )} </> ), render: (_, field) => { const fieldSchema = { type: 'object', properties: { [dataIndex]: { ...itemSchema[dataIndex], fieldCol: 24, } } }; if (!islidatePopover) { return ( <div className='fr-table-cell-content'> {renderCore({ parentPath: [field.name], rootPath: [...rootPath, field.name], schema: fieldSchema })} </div> ) } return ( <TableCell renderCore={renderCore} schema={fieldSchema} parentPath={[field.name]} rootPath={[...rootPath, field.name]} dataIndex={dataIndex} /> ); } }; }).filter(item => item); if (!readOnly && !hideOperate) { columns.push({ title: colHeaderText, width: '190px', fixed: 'right', ...otherActionColumnProps, render: (_, field) => ( <Form.Item> <Space className='fr-list-item-operate' split={operateBtnType !== 'icon' && <Divider type='vertical' />}> {!hideMove && ( <> <FButton disabled={field.name === 0} onClick={() => moveItem(field.name, field.name - 1)} icon={<ArrowUpOutlined />} {...moveUpBtnProps} /> <FButton disabled={field.name === fields.length - 1} onClick={() => moveItem(field.name, field.name + 1)} icon={<ArrowDownOutlined />} {...moveDownBtnProps} /> </> )} {!hideDelete && ( <Popconfirm onConfirm={() => removeItem(field.name)} {...delConfirmProps} > <FButton icon={<CloseOutlined />} btnType={operateBtnType} {...deleteBtnProps} /> </Popconfirm> )} {!hideCopy && ( <FButton onClick={() => handleCopy(field.name)} icon={<CopyOutlined />} {...copyBtnProps} /> )} </Space> </Form.Item> ) }); } const showTable = fields.length > 0 ? true : !hideEmptyTable; return ( <div className={classnames('fr-table-list', { 'fr-table-list-no-popover': !islidatePopover })}> {showTable && ( <Table size='middle' scroll={{ x: 'max-content' }} style={{ marginBottom: '12px' }} {...retProps} columns={columns} dataSource={fields} pagination={paginationConfig} /> )} {(!schema.max || fields.length < schema.max) && !hideAdd && ( <Button icon={<PlusOutlined />} onClick={() => addItem()} {...addBtnProps} /> )} </div> ); } export default TableList;