feat: improve code
This commit is contained in:
		
							parent
							
								
									585d9dd580
								
							
						
					
					
						commit
						bcc42a9455
					
				| @ -38,7 +38,7 @@ const InternalField: React.FC = (props) => { | |||||||
|   if (!uiSchema) { |   if (!uiSchema) { | ||||||
|     return null; |     return null; | ||||||
|   } |   } | ||||||
|   return React.createElement(component, props); |   return React.createElement(component, props, props.children); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const CollectionField = connect((props) => { | export const CollectionField = connect((props) => { | ||||||
|  | |||||||
| @ -8,13 +8,14 @@ import { | |||||||
|   useDataSourceFromRAC |   useDataSourceFromRAC | ||||||
| } from './'; | } from './'; | ||||||
| import * as hooks from './action-hooks'; | import * as hooks from './action-hooks'; | ||||||
| import { DataSourceProvider, ds } from './sub-table'; | import { DataSourceProvider, ds, SubFieldDataSourceProvider } from './sub-table'; | ||||||
| 
 | 
 | ||||||
| export const CollectionManagerSchemaComponentProvider: React.FC = (props) => { | export const CollectionManagerSchemaComponentProvider: React.FC = (props) => { | ||||||
|   return ( |   return ( | ||||||
|     <SchemaComponentOptions |     <SchemaComponentOptions | ||||||
|       scope={{ cm: { ...hooks, useDataSourceFromRAC }, ds }} |       scope={{ cm: { ...hooks, useDataSourceFromRAC }, ds }} | ||||||
|       components={{ |       components={{ | ||||||
|  |         SubFieldDataSourceProvider, | ||||||
|         DataSourceProvider, |         DataSourceProvider, | ||||||
|         CollectionField, |         CollectionField, | ||||||
|         CollectionFieldProvider, |         CollectionFieldProvider, | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ import { CollectionContext } from './context'; | |||||||
| import { useCollectionManager } from './hooks'; | import { useCollectionManager } from './hooks'; | ||||||
| import { CollectionOptions } from './types'; | import { CollectionOptions } from './types'; | ||||||
| 
 | 
 | ||||||
| export const CollectionProvider: React.FC<{ name?: string; collection: CollectionOptions }> = (props) => { | export const CollectionProvider: React.FC<{ name?: string; collection?: CollectionOptions }> = (props) => { | ||||||
|   const { name, collection, children } = props; |   const { name, collection, children } = props; | ||||||
|   const { get } = useCollectionManager(); |   const { get } = useCollectionManager(); | ||||||
|   return ( |   return ( | ||||||
|  | |||||||
| @ -33,7 +33,7 @@ export const subTable: IField = { | |||||||
|     ...defaultProps, |     ...defaultProps, | ||||||
|     subtable: { |     subtable: { | ||||||
|       type: 'void', |       type: 'void', | ||||||
|       'x-component': 'DataSourceProvider', |       'x-component': 'SubFieldDataSourceProvider', | ||||||
|       properties: { |       properties: { | ||||||
|         actions: { |         actions: { | ||||||
|           type: 'void', |           type: 'void', | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| import { observer, useForm } from '@formily/react'; | import { observer, useForm } from '@formily/react'; | ||||||
|  | import { cloneDeep } from 'lodash'; | ||||||
| import React, { createContext, useContext, useState } from 'react'; | import React, { createContext, useContext, useState } from 'react'; | ||||||
| import { CollectionOptions, CollectionProvider, useActionContext, useRecord, useRequest } from '../'; | import { CollectionOptions, CollectionProvider, useActionContext, useRecord, useRequest } from '../'; | ||||||
| import { useAPIClient } from '../api-client'; | import { useAPIClient } from '../api-client'; | ||||||
| @ -88,11 +89,12 @@ const useCreateAction = () => { | |||||||
|   const { setVisible } = useActionContext(); |   const { setVisible } = useActionContext(); | ||||||
|   return { |   return { | ||||||
|     async run() { |     async run() { | ||||||
|       // console.log(ctx.dataSource);
 |       console.log('form.values', form.values); | ||||||
|       const dataSource = ctx.dataSource || []; |       const dataSource = ctx.dataSource || []; | ||||||
|       dataSource.push(form.values); |       dataSource.push(cloneDeep(form.values)); | ||||||
|       ctx.setDataSource([...dataSource]); |       ctx.setDataSource([...dataSource]); | ||||||
|       setVisible(false); |       setVisible(false); | ||||||
|  |       await form.reset(); | ||||||
|     }, |     }, | ||||||
|   }; |   }; | ||||||
| }; | }; | ||||||
| @ -159,7 +161,7 @@ export const ds = { | |||||||
|   useDestroyAction, |   useDestroyAction, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const DataSourceProvider = observer((props) => { | export const SubFieldDataSourceProvider = observer((props) => { | ||||||
|   const [selectedRowKeys, setSelectedRowKeys] = useState([]); |   const [selectedRowKeys, setSelectedRowKeys] = useState([]); | ||||||
|   const [dataSource, setDataSource] = useState([]); |   const [dataSource, setDataSource] = useState([]); | ||||||
|   const record = useRecord(); |   const record = useRecord(); | ||||||
| @ -212,3 +214,50 @@ export const DataSourceProvider = observer((props) => { | |||||||
|     </CollectionProvider> |     </CollectionProvider> | ||||||
|   ); |   ); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | export const DataSourceProvider = observer((props: any) => { | ||||||
|  |   const { rowKey = 'id', collection, association } = props; | ||||||
|  |   const [selectedRowKeys, setSelectedRowKeys] = useState([]); | ||||||
|  |   const [dataSource, setDataSource] = useState([]); | ||||||
|  |   const record = useRecord(); | ||||||
|  |   const api = useAPIClient(); | ||||||
|  |   const resourceOf = record?.[association.targetKey || 'id']; | ||||||
|  |   console.log('record', record); | ||||||
|  |   const service = useRequest( | ||||||
|  |     () => { | ||||||
|  |       if (resourceOf) { | ||||||
|  |         return api | ||||||
|  |           .request({ | ||||||
|  |             resource: `${collection}.${association.name}`, | ||||||
|  |             resourceOf, | ||||||
|  |             action: 'list', | ||||||
|  |           }) | ||||||
|  |           .then((res) => res.data); | ||||||
|  |       } | ||||||
|  |       return Promise.resolve({ | ||||||
|  |         data: record?.[association.name] || [], | ||||||
|  |       }); | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       onSuccess(data) { | ||||||
|  |         setDataSource(data?.data); | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |   ); | ||||||
|  |   return ( | ||||||
|  |     <CollectionProvider name={collection}> | ||||||
|  |       <DataSourceContext.Provider | ||||||
|  |         value={{ | ||||||
|  |           rowKey, | ||||||
|  |           service, | ||||||
|  |           dataSource, | ||||||
|  |           setDataSource, | ||||||
|  |           selectedRowKeys, | ||||||
|  |           setSelectedRowKeys, | ||||||
|  |         }} | ||||||
|  |       > | ||||||
|  |         {props.children} | ||||||
|  |       </DataSourceContext.Provider> | ||||||
|  |     </CollectionProvider> | ||||||
|  |   ); | ||||||
|  | }); | ||||||
|  | |||||||
| @ -1,11 +1,10 @@ | |||||||
| import { observer } from '@formily/react'; | import { observer } from '@formily/react'; | ||||||
| import React from 'react'; | import React from 'react'; | ||||||
| import { Link } from 'react-router-dom'; |  | ||||||
| import Action from './Action'; | import Action from './Action'; | ||||||
| import { ComposedAction } from './types'; | import { ComposedAction } from './types'; | ||||||
| 
 | 
 | ||||||
| export const ActionLink: ComposedAction = observer((props: any) => { | export const ActionLink: ComposedAction = observer((props: any) => { | ||||||
|   return <Action {...props} component={Link} className={'nb-action-link'}/>; |   return <Action {...props} component={'a'} className={'nb-action-link'}/>; | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export default ActionLink; | export default ActionLink; | ||||||
|  | |||||||
| @ -72,7 +72,9 @@ export const Action: ComposedAction = observer((props: any) => { | |||||||
|     <ActionContext.Provider value={{ visible, setVisible, openMode, containerRefKey }}> |     <ActionContext.Provider value={{ visible, setVisible, openMode, containerRefKey }}> | ||||||
|       <SortableItem |       <SortableItem | ||||||
|         {...others} |         {...others} | ||||||
|         onClick={(e) => { |         onClick={(e: React.MouseEvent) => { | ||||||
|  |           e.preventDefault(); | ||||||
|  |           e.stopPropagation(); | ||||||
|           const onOk = () => { |           const onOk = () => { | ||||||
|             onClick?.(e); |             onClick?.(e); | ||||||
|             setVisible(true); |             setVisible(true); | ||||||
|  | |||||||
| @ -0,0 +1,171 @@ | |||||||
|  | import { ISchema } from '@formily/react'; | ||||||
|  | import { Switch } from 'antd'; | ||||||
|  | import React from 'react'; | ||||||
|  | import { SchemaInitializer } from '../../SchemaInitializer'; | ||||||
|  | import { useCurrentSchema } from '../utils'; | ||||||
|  | 
 | ||||||
|  | export const SubTableFieldInitializer = (props) => { | ||||||
|  |   const { item, insert } = props; | ||||||
|  |   const { exists, remove } = useCurrentSchema( | ||||||
|  |     item.schema['x-collection-field'], | ||||||
|  |     'x-collection-field', | ||||||
|  |     item.find, | ||||||
|  |     item.remove, | ||||||
|  |   ); | ||||||
|  |   return ( | ||||||
|  |     <SchemaInitializer.Item | ||||||
|  |       onClick={() => { | ||||||
|  |         console.log(item, exists); | ||||||
|  |         if (exists) { | ||||||
|  |           return remove(); | ||||||
|  |         } | ||||||
|  |         insert({ | ||||||
|  |           ...item.schema, | ||||||
|  |           properties: { | ||||||
|  |             block: { | ||||||
|  |               type: 'void', | ||||||
|  |               'x-component': 'DataSourceProvider', | ||||||
|  |               'x-component-props': { | ||||||
|  |                 rowKey: 'id', | ||||||
|  |                 collection: item?.field?.target, | ||||||
|  |                 association: { | ||||||
|  |                   name: item.field.name, | ||||||
|  |                   sourceKey: item.field.sourceKey, | ||||||
|  |                   targetKey: item.field.targetKey, | ||||||
|  |                 }, | ||||||
|  |               }, | ||||||
|  |               properties: { | ||||||
|  |                 actions: { | ||||||
|  |                   type: 'void', | ||||||
|  |                   'x-component': 'ActionBar', | ||||||
|  |                   'x-component-props': { | ||||||
|  |                     style: { | ||||||
|  |                       marginBottom: 16, | ||||||
|  |                     }, | ||||||
|  |                   }, | ||||||
|  |                   properties: { | ||||||
|  |                     delete: { | ||||||
|  |                       type: 'void', | ||||||
|  |                       title: '{{ t("Delete") }}', | ||||||
|  |                       'x-component': 'Action', | ||||||
|  |                       'x-component-props': { | ||||||
|  |                         useAction: '{{ ds.useBulkDestroyAction }}', | ||||||
|  |                         confirm: { | ||||||
|  |                           title: "{{t('Delete record')}}", | ||||||
|  |                           content: "{{t('Are you sure you want to delete it?')}}", | ||||||
|  |                         }, | ||||||
|  |                       }, | ||||||
|  |                     }, | ||||||
|  |                     create: { | ||||||
|  |                       type: 'void', | ||||||
|  |                       title: '{{ t("Add new") }}', | ||||||
|  |                       'x-action': 'create', | ||||||
|  |                       'x-component': 'Action', | ||||||
|  |                       'x-component-props': { | ||||||
|  |                         type: 'primary', | ||||||
|  |                         openMode: 'drawer', | ||||||
|  |                       }, | ||||||
|  |                       properties: { | ||||||
|  |                         drawer: { | ||||||
|  |                           type: 'void', | ||||||
|  |                           title: '{{ t("Add new record") }}', | ||||||
|  |                           'x-component': 'Action.Container', | ||||||
|  |                           'x-component-props': {}, | ||||||
|  |                           'x-decorator': 'Form', | ||||||
|  |                           properties: { | ||||||
|  |                             grid: { | ||||||
|  |                               type: 'void', | ||||||
|  |                               'x-component': 'Grid', | ||||||
|  |                               'x-initializer': 'GridFormItemInitializers', | ||||||
|  |                               properties: {}, | ||||||
|  |                             }, | ||||||
|  |                             footer: { | ||||||
|  |                               type: 'void', | ||||||
|  |                               'x-component': 'Action.Container.Footer', | ||||||
|  |                               properties: { | ||||||
|  |                                 actions: { | ||||||
|  |                                   type: 'void', | ||||||
|  |                                   'x-component': 'ActionBar', | ||||||
|  |                                   'x-component-props': { | ||||||
|  |                                     layout: 'one-column', | ||||||
|  |                                   }, | ||||||
|  |                                   properties: { | ||||||
|  |                                     cancel: { | ||||||
|  |                                       title: '{{ t("Cancel") }}', | ||||||
|  |                                       'x-action': 'cancel', | ||||||
|  |                                       'x-component': 'Action', | ||||||
|  |                                       'x-component-props': { | ||||||
|  |                                         useAction: '{{ cm.useCancelAction }}', | ||||||
|  |                                       }, | ||||||
|  |                                     }, | ||||||
|  |                                     submit: { | ||||||
|  |                                       title: '{{ t("Submit") }}', | ||||||
|  |                                       'x-action': 'submit', | ||||||
|  |                                       'x-component': 'Action', | ||||||
|  |                                       'x-component-props': { | ||||||
|  |                                         type: 'primary', | ||||||
|  |                                         useAction: '{{ ds.useCreateAction }}', | ||||||
|  |                                       }, | ||||||
|  |                                     }, | ||||||
|  |                                   }, | ||||||
|  |                                 }, | ||||||
|  |                               }, | ||||||
|  |                             }, | ||||||
|  |                           }, | ||||||
|  |                         }, | ||||||
|  |                       }, | ||||||
|  |                     }, | ||||||
|  |                   }, | ||||||
|  |                 }, | ||||||
|  |                 [item.field.name]: { | ||||||
|  |                   type: 'array', | ||||||
|  |                   title: '{{t("Fields")}}', | ||||||
|  |                   'x-component': 'Table.Array', | ||||||
|  |                   'x-initializer': 'TableColumnInitializers', | ||||||
|  |                   'x-component-props': { | ||||||
|  |                     pagination: false, | ||||||
|  |                     expandable: { | ||||||
|  |                       childrenColumnName: '__nochildren__', | ||||||
|  |                     }, | ||||||
|  |                     rowKey: 'id', | ||||||
|  |                     rowSelection: { | ||||||
|  |                       type: 'checkbox', | ||||||
|  |                     }, | ||||||
|  |                     useSelectedRowKeys: '{{ ds.useSelectedRowKeys }}', | ||||||
|  |                     useDataSource: '{{ ds.useDataSource }}', | ||||||
|  |                     // scroll: { x: '100%' },
 | ||||||
|  |                   }, | ||||||
|  |                   properties: { | ||||||
|  |                     actions: { | ||||||
|  |                       type: 'void', | ||||||
|  |                       title: '{{ t("Actions") }}', | ||||||
|  |                       'x-decorator': 'Table.Column.ActionBar', | ||||||
|  |                       'x-component': 'Table.Column', | ||||||
|  |                       'x-designer': 'Table.RowActionDesigner', | ||||||
|  |                       'x-initializer': 'TableRecordActionInitializers', | ||||||
|  |                       properties: { | ||||||
|  |                         actions: { | ||||||
|  |                           type: 'void', | ||||||
|  |                           'x-decorator': 'DndContext', | ||||||
|  |                           'x-component': 'Space', | ||||||
|  |                           'x-component-props': { | ||||||
|  |                             split: '|', | ||||||
|  |                           }, | ||||||
|  |                           properties: {}, | ||||||
|  |                         }, | ||||||
|  |                       }, | ||||||
|  |                     }, | ||||||
|  |                   }, | ||||||
|  |                 }, | ||||||
|  |               }, | ||||||
|  |             }, | ||||||
|  |           }, | ||||||
|  |         } as ISchema); | ||||||
|  |       }} | ||||||
|  |     > | ||||||
|  |       <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> | ||||||
|  |         {item.title} <Switch style={{ marginLeft: 20 }} size={'small'} checked={exists} /> | ||||||
|  |       </div> | ||||||
|  |     </SchemaInitializer.Item> | ||||||
|  |   ); | ||||||
|  | }; | ||||||
| @ -5,5 +5,6 @@ export * from './CollectionFieldInitializer'; | |||||||
| export * from './FormBlockInitializer'; | export * from './FormBlockInitializer'; | ||||||
| export * from './GeneralInitializer'; | export * from './GeneralInitializer'; | ||||||
| export * from './MarkdownBlockInitializer'; | export * from './MarkdownBlockInitializer'; | ||||||
|  | export * from './SubTableFieldInitializer'; | ||||||
| export * from './TableBlockInitializer'; | export * from './TableBlockInitializer'; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -12,7 +12,6 @@ export const TableRecordActionInitializers = (props: any) => { | |||||||
|   const api = useAPIClient(); |   const api = useAPIClient(); | ||||||
|   const { refresh } = useDesignable(); |   const { refresh } = useDesignable(); | ||||||
|   const { t } = useTranslation(); |   const { t } = useTranslation(); | ||||||
|   console.log('TableRecordActionInitializers'); |  | ||||||
|   return ( |   return ( | ||||||
|     <SchemaInitializer.Button |     <SchemaInitializer.Button | ||||||
|       className={css` |       className={css` | ||||||
| @ -118,7 +117,7 @@ export const TableRecordActionInitializers = (props: any) => { | |||||||
|                       grid: { |                       grid: { | ||||||
|                         type: 'void', |                         type: 'void', | ||||||
|                         'x-component': 'Grid', |                         'x-component': 'Grid', | ||||||
|                         'x-item-initializer': 'FormItemInitializer', |                         'x-initializer': 'GridFormItemInitializers', | ||||||
|                         properties: {}, |                         properties: {}, | ||||||
|                       }, |                       }, | ||||||
|                       footer: { |                       footer: { | ||||||
| @ -127,7 +126,7 @@ export const TableRecordActionInitializers = (props: any) => { | |||||||
|                         properties: { |                         properties: { | ||||||
|                           actions: { |                           actions: { | ||||||
|                             type: 'void', |                             type: 'void', | ||||||
|                             'x-action-initializer': 'PopupFormActionInitializer', |                             'x-initializer': 'PopupFormActionInitializers', | ||||||
|                             'x-decorator': 'DndContext', |                             'x-decorator': 'DndContext', | ||||||
|                             'x-component': 'ActionBar', |                             'x-component': 'ActionBar', | ||||||
|                             'x-component-props': { |                             'x-component-props': { | ||||||
| @ -167,4 +166,4 @@ export const TableRecordActionInitializers = (props: any) => { | |||||||
|       <MenuOutlined /> |       <MenuOutlined /> | ||||||
|     </SchemaInitializer.Button> |     </SchemaInitializer.Button> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
| @ -23,9 +23,9 @@ export const gridRowColWrap = (schema: ISchema) => { | |||||||
| export const removeTableColumn = (schema, cb) => { | export const removeTableColumn = (schema, cb) => { | ||||||
|   cb(schema, { |   cb(schema, { | ||||||
|     removeParentsIfNoChildren: true, |     removeParentsIfNoChildren: true, | ||||||
|     breakRemoveOn: { |     // breakRemoveOn: (s) => {
 | ||||||
|       'x-component': 'ArrayTable', |     //   return s['x-component'].startsWith('Table.');
 | ||||||
|     }, |     // },
 | ||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -38,6 +38,24 @@ export const removeGridFormItem = (schema, cb) => { | |||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | const findTableColumn = (schema: Schema, key: string, action: string, deepth: number = 0) => { | ||||||
|  |   return schema.reduceProperties((buf, s) => { | ||||||
|  |     if (s[key] === action) { | ||||||
|  |       return s; | ||||||
|  |     } | ||||||
|  |     const c = s.reduceProperties((buf, s) => { | ||||||
|  |       if (s[key] === action) { | ||||||
|  |         return s; | ||||||
|  |       } | ||||||
|  |       return buf; | ||||||
|  |     }); | ||||||
|  |     if (c) { | ||||||
|  |       return c; | ||||||
|  |     } | ||||||
|  |     return buf; | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| export const useTableColumnInitializerFields = () => { | export const useTableColumnInitializerFields = () => { | ||||||
|   const { name, fields } = useCollection(); |   const { name, fields } = useCollection(); | ||||||
|   return ( |   return ( | ||||||
| @ -53,6 +71,7 @@ export const useTableColumnInitializerFields = () => { | |||||||
|             'x-component': 'CollectionField', |             'x-component': 'CollectionField', | ||||||
|           }, |           }, | ||||||
|           component: 'CollectionFieldInitializer', |           component: 'CollectionFieldInitializer', | ||||||
|  |           find: findTableColumn, | ||||||
|           remove: removeTableColumn, |           remove: removeTableColumn, | ||||||
|         } as SchemaInitializerItemOptions; |         } as SchemaInitializerItemOptions; | ||||||
|       }) |       }) | ||||||
| @ -62,6 +81,23 @@ export const useTableColumnInitializerFields = () => { | |||||||
| export const useFormItemInitializerFields = () => { | export const useFormItemInitializerFields = () => { | ||||||
|   const { name, fields } = useCollection(); |   const { name, fields } = useCollection(); | ||||||
|   return fields?.map((field) => { |   return fields?.map((field) => { | ||||||
|  |     if (field.interface === 'subTable') { | ||||||
|  |       return { | ||||||
|  |         type: 'item', | ||||||
|  |         title: field?.uiSchema?.title || field.name, | ||||||
|  |         component: 'SubTableFieldInitializer', | ||||||
|  |         remove: removeGridFormItem, | ||||||
|  |         field, | ||||||
|  |         schema: { | ||||||
|  |           type: 'void', | ||||||
|  |           name: field.name, | ||||||
|  |           'x-designer': 'FormItem.Designer', | ||||||
|  |           'x-component': 'div', | ||||||
|  |           'x-decorator': 'FormItem', | ||||||
|  |           'x-collection-field': `${name}.${field.name}`, | ||||||
|  |         }, | ||||||
|  |       } as SchemaInitializerItemOptions; | ||||||
|  |     } | ||||||
|     return { |     return { | ||||||
|       type: 'item', |       type: 'item', | ||||||
|       title: field?.uiSchema?.title || field.name, |       title: field?.uiSchema?.title || field.name, | ||||||
|  | |||||||
| @ -39,7 +39,7 @@ interface ItemOptions extends ItemCommonOptions { | |||||||
|   component?: any; |   component?: any; | ||||||
|   schema?: ISchema; |   schema?: ISchema; | ||||||
|   remove?: (schema: Schema, cb: RemoveCallback) => void; |   remove?: (schema: Schema, cb: RemoveCallback) => void; | ||||||
|   find?: (schema: Schema, current: string) => Schema | null | undefined; |   find?: (schema: Schema, key?: string, current?: string) => Schema | null | undefined; | ||||||
|   [key: string]: any; |   [key: string]: any; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user