feat: support for displaying relational table fields in details or form blocks (#635)
* feat: m2o association field * feat: add ReadPrettyForm support
This commit is contained in:
		
							parent
							
								
									a521231a25
								
							
						
					
					
						commit
						9df35933d2
					
				| @ -204,7 +204,7 @@ FormItem.Designer = (props) => { | |||||||
|           }} |           }} | ||||||
|         /> |         /> | ||||||
|       )} |       )} | ||||||
|       {validateSchema && ( |       {form && !form?.readPretty && validateSchema && ( | ||||||
|         <SchemaSettings.ModalItem |         <SchemaSettings.ModalItem | ||||||
|           title={t('Set validation rules')} |           title={t('Set validation rules')} | ||||||
|           components={{ ArrayCollapse, FormLayout }} |           components={{ ArrayCollapse, FormLayout }} | ||||||
| @ -371,7 +371,7 @@ FormItem.Designer = (props) => { | |||||||
|           }} |           }} | ||||||
|         /> |         /> | ||||||
|       )} |       )} | ||||||
|       {form && !form?.readPretty && collectionField?.interface !== 'o2m' && ( |       {form && !form?.readPretty && collectionField?.interface !== 'o2m' && fieldSchema?.['x-component-props']?.['pattern-disable'] != true && ( | ||||||
|         <SchemaSettings.SelectItem |         <SchemaSettings.SelectItem | ||||||
|           key="pattern" |           key="pattern" | ||||||
|           title={t('Pattern')} |           title={t('Pattern')} | ||||||
|  | |||||||
| @ -59,6 +59,23 @@ export const KanbanCardDesigner = (props: any) => { | |||||||
|   const field = useField(); |   const field = useField(); | ||||||
|   const fieldSchema = useFieldSchema(); |   const fieldSchema = useFieldSchema(); | ||||||
|   const fields = useFormItemInitializerFields({ readPretty: true, block: 'Kanban' }); |   const fields = useFormItemInitializerFields({ readPretty: true, block: 'Kanban' }); | ||||||
|  |   const associationFields = useAssociatedFormItemInitializerFields({readPretty: true, block: 'Kanban'}); | ||||||
|  |    | ||||||
|  |   const items: any = [{ | ||||||
|  |     type: 'itemGroup', | ||||||
|  |     title: t('Display fields'), | ||||||
|  |     children: fields, | ||||||
|  |   }]; | ||||||
|  |   if (associationFields.length > 0) { | ||||||
|  |     items.push({ | ||||||
|  |       type: 'divider', | ||||||
|  |     }, { | ||||||
|  |       type: 'itemGroup', | ||||||
|  |       title: t('Display association fields'), | ||||||
|  |       children: associationFields, | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |    | ||||||
|   if (!designable) { |   if (!designable) { | ||||||
|     return null; |     return null; | ||||||
|   } |   } | ||||||
| @ -87,21 +104,7 @@ export const KanbanCardDesigner = (props: any) => { | |||||||
|               dn.loadAPIClientEvents(); |               dn.loadAPIClientEvents(); | ||||||
|               dn.insertBeforeEnd(schema); |               dn.insertBeforeEnd(schema); | ||||||
|             }} |             }} | ||||||
|             items={[ |             items={items} | ||||||
|               { |  | ||||||
|                 type: 'itemGroup', |  | ||||||
|                 title: t('Display fields'), |  | ||||||
|                 children: fields, |  | ||||||
|               }, |  | ||||||
|               { |  | ||||||
|                 type: 'divider', |  | ||||||
|               }, |  | ||||||
|               { |  | ||||||
|                 type: 'itemGroup', |  | ||||||
|                 title: t('Display association fields'), |  | ||||||
|                 children: useAssociatedFormItemInitializerFields({readPretty: true, block: 'Kanban'}), |  | ||||||
|               }, |  | ||||||
|             ]} |  | ||||||
|             component={<MenuOutlined style={{ cursor: 'pointer', fontSize: 12 }} />} |             component={<MenuOutlined style={{ cursor: 'pointer', fontSize: 12 }} />} | ||||||
|           /> |           /> | ||||||
|         </Space> |         </Space> | ||||||
|  | |||||||
| @ -1,23 +1,33 @@ | |||||||
| import React from 'react'; | import React from 'react'; | ||||||
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||||
| import { SchemaInitializer } from '../SchemaInitializer'; | import { SchemaInitializer } from '../SchemaInitializer'; | ||||||
| import { gridRowColWrap, useFormItemInitializerFields } from '../utils'; | import { gridRowColWrap, useAssociatedFormItemInitializerFields, useFormItemInitializerFields } from '../utils'; | ||||||
|  | import { union } from 'lodash'; | ||||||
| 
 | 
 | ||||||
| // 表单里配置字段
 | // 表单里配置字段
 | ||||||
| export const FormItemInitializers = (props: any) => { | export const FormItemInitializers = (props: any) => { | ||||||
|   const { t } = useTranslation(); |   const { t } = useTranslation(); | ||||||
|   const { insertPosition, component } = props; |   const { insertPosition, component } = props; | ||||||
|  |   const associationFields = useAssociatedFormItemInitializerFields({readPretty: true, block: 'Form'}); | ||||||
|  | 
 | ||||||
|   return ( |   return ( | ||||||
|     <SchemaInitializer.Button |     <SchemaInitializer.Button | ||||||
|       wrap={gridRowColWrap} |       wrap={gridRowColWrap} | ||||||
|       icon={'SettingOutlined'} |       icon={'SettingOutlined'} | ||||||
|       items={[ |       items={union([ | ||||||
|         { |         { | ||||||
|           type: 'itemGroup', |           type: 'itemGroup', | ||||||
|           title: t('Display fields'), |           title: t('Display fields'), | ||||||
|           children: useFormItemInitializerFields(), |           children: useFormItemInitializerFields(), | ||||||
|         }, |         }], | ||||||
|         { |         associationFields.length > 0 ? [{ | ||||||
|  |           type: 'divider', | ||||||
|  |         }, { | ||||||
|  |           type: 'itemGroup', | ||||||
|  |           title: t('Display association fields'), | ||||||
|  |           children: associationFields, | ||||||
|  |         }] : [], | ||||||
|  |         [{ | ||||||
|           type: 'divider', |           type: 'divider', | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
| @ -35,7 +45,7 @@ export const FormItemInitializers = (props: any) => { | |||||||
|             }, |             }, | ||||||
|           }, |           }, | ||||||
|         }, |         }, | ||||||
|       ]} |       ])} | ||||||
|       insertPosition={insertPosition} |       insertPosition={insertPosition} | ||||||
|       component={component} |       component={component} | ||||||
|       title={component ? null : t('Configure fields')} |       title={component ? null : t('Configure fields')} | ||||||
|  | |||||||
| @ -1,22 +1,32 @@ | |||||||
| import React from 'react'; | import React from 'react'; | ||||||
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||||
| import { SchemaInitializer } from '../SchemaInitializer'; | import { SchemaInitializer } from '../SchemaInitializer'; | ||||||
| import { gridRowColWrap, useFormItemInitializerFields } from '../utils'; | import { gridRowColWrap, useAssociatedFormItemInitializerFields, useFormItemInitializerFields } from '../utils'; | ||||||
|  | import { union } from 'lodash'; | ||||||
| 
 | 
 | ||||||
| export const ReadPrettyFormItemInitializers = (props: any) => { | export const ReadPrettyFormItemInitializers = (props: any) => { | ||||||
|   const { t } = useTranslation(); |   const { t } = useTranslation(); | ||||||
|   const { insertPosition, component } = props; |   const { insertPosition, component } = props; | ||||||
|  |   const associationFields = useAssociatedFormItemInitializerFields({readPretty: true, block: 'Form'}); | ||||||
|  |    | ||||||
|   return ( |   return ( | ||||||
|     <SchemaInitializer.Button |     <SchemaInitializer.Button | ||||||
|       wrap={gridRowColWrap} |       wrap={gridRowColWrap} | ||||||
|       icon={'SettingOutlined'} |       icon={'SettingOutlined'} | ||||||
|       items={[ |       items={union([ | ||||||
|         { |         { | ||||||
|           type: 'itemGroup', |           type: 'itemGroup', | ||||||
|           title: t('Display fields'), |           title: t('Display fields'), | ||||||
|           children: useFormItemInitializerFields(), |           children: useFormItemInitializerFields(), | ||||||
|         }, |         }], | ||||||
|         { |         associationFields.length > 0 ? [{ | ||||||
|  |           type: 'divider', | ||||||
|  |         }, { | ||||||
|  |           type: 'itemGroup', | ||||||
|  |           title: t('Display association fields'), | ||||||
|  |           children: associationFields, | ||||||
|  |         }] : [], | ||||||
|  |         [{ | ||||||
|           type: 'divider', |           type: 'divider', | ||||||
|         }, |         }, | ||||||
|         { |         { | ||||||
| @ -34,7 +44,7 @@ export const ReadPrettyFormItemInitializers = (props: any) => { | |||||||
|             }, |             }, | ||||||
|           }, |           }, | ||||||
|         }, |         }, | ||||||
|       ]} |       ])} | ||||||
|       insertPosition={insertPosition} |       insertPosition={insertPosition} | ||||||
|       component={component} |       component={component} | ||||||
|       title={component ? null : t('Configure fields')} |       title={component ? null : t('Configure fields')} | ||||||
|  | |||||||
| @ -193,10 +193,11 @@ export const useAssociatedFormItemInitializerFields = (options?: any) => { | |||||||
|   const { getInterface, getCollectionFields } = useCollectionManager(); |   const { getInterface, getCollectionFields } = useCollectionManager(); | ||||||
|   const form = useForm(); |   const form = useForm(); | ||||||
|   const { readPretty = form.readPretty, block = 'Form' } = options || {}; |   const { readPretty = form.readPretty, block = 'Form' } = options || {}; | ||||||
|  |   const interfaces = block === 'Form' ? ['m2o'] : ['o2o', 'oho', 'obo', 'm2o'] | ||||||
| 
 | 
 | ||||||
|   const groups = fields |   const groups = fields | ||||||
|     ?.filter((field) => { |     ?.filter((field) => { | ||||||
|       return ['o2o', 'oho', 'obo', 'm2o'].includes(field.interface); |       return interfaces.includes(field.interface); | ||||||
|     }) |     }) | ||||||
|     ?.map((field) => { |     ?.map((field) => { | ||||||
|       const subFields = getCollectionFields(field.target); |       const subFields = getCollectionFields(field.target); | ||||||
| @ -210,7 +211,9 @@ export const useAssociatedFormItemInitializerFields = (options?: any) => { | |||||||
|             // title: subField?.uiSchema?.title || subField.name,
 |             // title: subField?.uiSchema?.title || subField.name,
 | ||||||
|             'x-designer': 'FormItem.Designer', |             'x-designer': 'FormItem.Designer', | ||||||
|             'x-component': 'CollectionField', |             'x-component': 'CollectionField', | ||||||
|  |             'x-read-pretty': readPretty, | ||||||
|             'x-component-props': { |             'x-component-props': { | ||||||
|  |               'pattern-disable': block === 'Form' && readPretty, | ||||||
|             }, |             }, | ||||||
|             'x-decorator': 'FormItem', |             'x-decorator': 'FormItem', | ||||||
|             'x-collection-field': `${name}.${field.name}.${subField.name}`, |             'x-collection-field': `${name}.${field.name}.${subField.name}`, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user