Browse Source

完善RForm,外部可以自定义渲染或重写列的配置,增加左上角区域自定义渲染或配置

main
dark 3 months ago
parent
commit
cd901c21ef
  1. 85
      src/components/r-form/index.tsx
  2. 2
      src/layout/RootLayout.tsx
  3. 60
      src/pages/r-form/index.tsx

85
src/components/r-form/index.tsx

@ -13,15 +13,31 @@ import { BetaSchemaForm, ProColumns, ProFormColumnsType } from '@ant-design/pro-
import { useApiContext } from '@/context.ts'
import { useDeepCompareEffect } from 'react-use'
import { RFormTypes } from '@/types/r-form/model'
import { ProCoreActionType } from '@ant-design/pro-utils/es/typing'
export interface RFormProps {
title?: ReactNode
namespace?: string
columns?: ProColumns[] //重写columns
actions?: ReactNode[] | JSX.Element[] //左上角的操作按钮
toolbar?: ReactNode //工具栏
renderActions?: (addAction: ReactNode) => ReactNode //渲染操作按钮
resolveColumns?: (columns: ProColumns[]) => ProColumns[] //处理columns
renderColumnOptions?: (record: any, defaultOptions: ReactNode[], index: number, action: ProCoreActionType | undefined) => ReactNode //渲染列的操作
}
const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
const RForm = (
{
namespace,
actions = [],
toolbar,
resolveColumns,
renderActions,
renderColumnOptions,
columns: propColumns = [], title
}: RFormProps) => {
const { styles, cx } = useStyle()
const apiCtx = useApiContext()
@ -50,7 +66,33 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
useDeepCompareEffect(() => {
const res = transformAntdTableProColumns(curdModal?.columns || [], propColumns)
let res = transformAntdTableProColumns(curdModal?.columns || [], propColumns)
if (resolveColumns) {
res = resolveColumns(res)
}
const options = (record: any) => {
return [
<Action key="edit"
as={'a'}
onClick={() => {
form.setFieldsValue(record)
setOpen(true)
}}>{'编辑'}</Action>,
<Popconfirm
key={'del_confirm'}
disabled={isDeleting}
onConfirm={() => {
deleteModel([ record.id ])
}}
title={'确定要删除吗?'}>
<a key="del">
</a>
</Popconfirm>
]
}
const _columns = [ {
title: 'ID',
dataIndex: 'id',
@ -63,29 +105,16 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
dataIndex: 'option',
valueType: 'option',
fixed: 'right',
render: (_, record) => [
<Action key="edit"
as={'a'}
onClick={() => {
form.setFieldsValue(record)
setOpen(true)
}}>{'编辑'}</Action>,
<Popconfirm
key={'del_confirm'}
disabled={isDeleting}
onConfirm={() => {
deleteModel([ record.id ])
}}
title={'确定要删除吗?'}>
<a key="del">
</a>
</Popconfirm>
]
render: (_, record, index, action) => {
if (renderColumnOptions) {
return renderColumnOptions(record, options(record), index, action)
}
return options(record)
}
} as any
])
setColumns(_columns)
}, [ curdModal?.columns, propColumns, deleteModel, form, isDeleting, setOpen, ])
}, [ curdModal?.columns, propColumns, renderColumnOptions, resolveColumns, deleteModel, form, isDeleting, setOpen, ])
useEffect(() => {
if (apiCtx.isApi && apiCtx.api) {
@ -144,6 +173,15 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
type={'primary'}>{'添加'}</Button>
</>
const _renderActions = () => {
if (renderActions) {
return renderActions(tableTitle)
}
return <Space>
{[ tableTitle, ...actions ]}
</Space>
}
return (
<>
<ListPageLayout
@ -153,7 +191,7 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
<ProTable
{...curdModal?.table}
rowKey="id"
headerTitle={tableTitle}
headerTitle={_renderActions()}
toolbar={{
/*search: {
loading: isFetching && !!search?.key,
@ -247,6 +285,7 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
}}
loading={isSubmitting}
onFinish={async (values) => {
console.log(values)
saveOrUpdate(values as any)
}}
columns={columns as ProFormColumnsType[]}/>

2
src/layout/RootLayout.tsx

@ -127,7 +127,7 @@ export default () => {
color: '#00000012',
size: 17,
},
zindex: 1009,
zIndex: 1009,
} as any
} style={{ width: '100vw', height: '100vh' }}>
<ProLayout

60
src/pages/r-form/index.tsx

@ -1,10 +1,68 @@
import { createFileRoute } from '@tanstack/react-router'
import RForm from '@/components/r-form'
import { Button, Input, message, Modal } from 'antd'
import { ReactNode, useState } from 'react'
import { get, hasIn } from 'lodash'
import { ProCoreActionType } from '@ant-design/pro-utils/es/typing'
const RFormRender = () => {
const [ json, setJson ] = useState('')
const [ open, setOpen ] = useState(false)
const [ columns, setColumns ] = useState()
const actions = [
<Button key={'json'} onClick={() => {
setOpen(true)
}}>JSON</Button>
]
const renderOptions = (record: any, defaultOptions: ReactNode[], index: number, action: ProCoreActionType | undefined) => {
return [
...defaultOptions,
<Button key={'ext'} onClick={() => {
console.log('扩展按钮', record)
}}></Button>
]
}
return <>
<RForm/>
<RForm actions={actions}
renderColumnOptions={renderOptions}
resolveColumns={(cols) => columns ?? cols}/>
<Modal
title={'导入JSON'}
open={open}
afterOpenChange={setOpen}
onCancel={() => setOpen(false)}
onOk={() => {
try {
const data = JSON.parse(json)
//如果是Array, 检查元素是否为ProColumns
if (Array.isArray(data)) {
if (data.length > 0 && hasIn(data[0], 'dataIndex')) {
setColumns(data as any)
setOpen(false)
return
}
}
if (hasIn(data, 'data.page.columns')) {
setColumns(get(data, 'data.page.columns'))
setOpen(false)
return
}
message.error('JSON格式错误, 请确保是ProColumns或者包含data.page.columns的对象')
} catch (e) {
message.error('JSON格式错误')
}
}}
>
<Input.TextArea rows={10} value={json} onChange={(e) => {
setJson(e.target.value)
}}/>
<span style={{ color: '#aeaeae', lineHeight: 2.5 }}>Antd.Table.Columns数组或者xxx/ui/curd返回的结构</span>
</Modal>
</>
}

Loading…
Cancel
Save