Browse Source

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

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

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

@ -13,15 +13,31 @@ import { BetaSchemaForm, ProColumns, ProFormColumnsType } from '@ant-design/pro-
import { useApiContext } from '@/context.ts' import { useApiContext } from '@/context.ts'
import { useDeepCompareEffect } from 'react-use' import { useDeepCompareEffect } from 'react-use'
import { RFormTypes } from '@/types/r-form/model' import { RFormTypes } from '@/types/r-form/model'
import { ProCoreActionType } from '@ant-design/pro-utils/es/typing'
export interface RFormProps { export interface RFormProps {
title?: ReactNode title?: ReactNode
namespace?: string namespace?: string
columns?: ProColumns[] //重写columns 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 { styles, cx } = useStyle()
const apiCtx = useApiContext() const apiCtx = useApiContext()
@ -50,20 +66,13 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
useDeepCompareEffect(() => { useDeepCompareEffect(() => {
const res = transformAntdTableProColumns(curdModal?.columns || [], propColumns)
const _columns = [ {
title: 'ID',
dataIndex: 'id',
hideInTable: true,
hideInSearch: true,
formItemProps: { hidden: true }
} ].concat(res as any).concat([
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
fixed: 'right',
render: (_, record) => [
let res = transformAntdTableProColumns(curdModal?.columns || [], propColumns)
if (resolveColumns) {
res = resolveColumns(res)
}
const options = (record: any) => {
return [
<Action key="edit" <Action key="edit"
as={'a'} as={'a'}
onClick={() => { onClick={() => {
@ -82,10 +91,30 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
</a> </a>
</Popconfirm> </Popconfirm>
] ]
}
const _columns = [ {
title: 'ID',
dataIndex: 'id',
hideInTable: true,
hideInSearch: true,
formItemProps: { hidden: true }
} ].concat(res as any).concat([
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
fixed: 'right',
render: (_, record, index, action) => {
if (renderColumnOptions) {
return renderColumnOptions(record, options(record), index, action)
}
return options(record)
}
} as any } as any
]) ])
setColumns(_columns) setColumns(_columns)
}, [ curdModal?.columns, propColumns, deleteModel, form, isDeleting, setOpen, ])
}, [ curdModal?.columns, propColumns, renderColumnOptions, resolveColumns, deleteModel, form, isDeleting, setOpen, ])
useEffect(() => { useEffect(() => {
if (apiCtx.isApi && apiCtx.api) { if (apiCtx.isApi && apiCtx.api) {
@ -144,6 +173,15 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
type={'primary'}>{'添加'}</Button> type={'primary'}>{'添加'}</Button>
</> </>
const _renderActions = () => {
if (renderActions) {
return renderActions(tableTitle)
}
return <Space>
{[ tableTitle, ...actions ]}
</Space>
}
return ( return (
<> <>
<ListPageLayout <ListPageLayout
@ -153,7 +191,7 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
<ProTable <ProTable
{...curdModal?.table} {...curdModal?.table}
rowKey="id" rowKey="id"
headerTitle={tableTitle}
headerTitle={_renderActions()}
toolbar={{ toolbar={{
/*search: { /*search: {
loading: isFetching && !!search?.key, loading: isFetching && !!search?.key,
@ -247,6 +285,7 @@ const RForm = ({ namespace, columns: propColumns = [], title }: RFormProps) => {
}} }}
loading={isSubmitting} loading={isSubmitting}
onFinish={async (values) => { onFinish={async (values) => {
console.log(values)
saveOrUpdate(values as any) saveOrUpdate(values as any)
}} }}
columns={columns as ProFormColumnsType[]}/> columns={columns as ProFormColumnsType[]}/>

2
src/layout/RootLayout.tsx

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

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

@ -1,10 +1,68 @@
import { createFileRoute } from '@tanstack/react-router' import { createFileRoute } from '@tanstack/react-router'
import RForm from '@/components/r-form' 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 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 <> 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