feat: add filter action to collection table (#953)
* feat: 数据表支持筛选 * feat: 数据表支持筛选 * feat: 数据表支持筛选 * feat: 数据表支持筛选 * fix: format code Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
		
							parent
							
								
									40554d8151
								
							
						
					
					
						commit
						2c690a39e0
					
				| @ -4,7 +4,7 @@ import { uid } from '@formily/shared'; | ||||
| import React, { useContext, useEffect, useState } from 'react'; | ||||
| import { useRequest } from '../../api-client'; | ||||
| import { useRecord } from '../../record-provider'; | ||||
| import { SchemaComponent, useActionContext, useCompile } from '../../schema-component'; | ||||
| import { SchemaComponent, SchemaComponentContext, useActionContext, useCompile } from '../../schema-component'; | ||||
| import { useCollectionManager } from '../hooks/useCollectionManager'; | ||||
| import { DataSourceContext } from '../sub-table'; | ||||
| import { AddSubFieldAction } from './AddSubFieldAction'; | ||||
| @ -164,11 +164,11 @@ const useCurrentFields = () => { | ||||
|   const { getCollectionFields } = useCollectionManager(); | ||||
|   const fields = getCollectionFields(record.collectionName || record.name) as any[]; | ||||
|   return fields; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| const useNewId = (prefix) => { | ||||
|   return `${prefix || ''}${uid()}`; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export const ConfigurationTable = () => { | ||||
|   const { collections = [] } = useCollectionManager(); | ||||
| @ -179,8 +179,10 @@ export const ConfigurationTable = () => { | ||||
|       value: item.name, | ||||
|     })); | ||||
|   }; | ||||
|   const ctx = useContext(SchemaComponentContext); | ||||
|   return ( | ||||
|     <div> | ||||
|       <SchemaComponentContext.Provider value={{ ...ctx, designable: false }}> | ||||
|         <SchemaComponent | ||||
|           schema={collectionSchema} | ||||
|           components={{ | ||||
| @ -199,6 +201,7 @@ export const ConfigurationTable = () => { | ||||
|             useNewId, | ||||
|           }} | ||||
|         /> | ||||
|       </SchemaComponentContext.Provider> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| @ -5,9 +5,9 @@ import { collectionFieldSchema } from './collectionFields'; | ||||
| 
 | ||||
| const compile = (source) => { | ||||
|   return Schema.compile(source, { t: i18n.t }); | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| const collection: CollectionOptions = { | ||||
| export const collection: CollectionOptions = { | ||||
|   name: 'collections', | ||||
|   filterTargetKey: 'name', | ||||
|   targetKey: 'name', | ||||
| @ -31,7 +31,8 @@ const collection: CollectionOptions = { | ||||
|         title: '{{ t("Collection name") }}', | ||||
|         type: 'string', | ||||
|         'x-component': 'Input', | ||||
|         description: '{{t("Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.")}}', | ||||
|         description: | ||||
|           '{{t("Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.")}}', | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
| @ -82,6 +83,20 @@ export const collectionSchema: ISchema = { | ||||
|             }, | ||||
|           }, | ||||
|           properties: { | ||||
|             filter: { | ||||
|               type: 'void', | ||||
|               title: '{{ t("Filter") }}', | ||||
|               default: { | ||||
|                 $and: [{ title: { $includes: '' } }, { name: { $includes: '' } }], | ||||
|               }, | ||||
|               'x-action': 'filter', | ||||
|               'x-component': 'Filter.Action', | ||||
|               'x-component-props': { | ||||
|                 icon: 'FilterOutlined', | ||||
|                 useProps: '{{ cm.useFilterActionProps }}', | ||||
|               }, | ||||
|               'x-align': 'left', | ||||
|             }, | ||||
|             delete: { | ||||
|               type: 'void', | ||||
|               title: '{{ t("Delete") }}', | ||||
|  | ||||
| @ -1,12 +1,13 @@ | ||||
| import { useForm } from '@formily/react'; | ||||
| import { message } from 'antd'; | ||||
| import omit from 'lodash/omit'; | ||||
| import { useEffect } from 'react'; | ||||
| import { useForm } from '@formily/react'; | ||||
| import { useCollection, useCollectionManager } from '.'; | ||||
| import { useRequest } from '../api-client'; | ||||
| import { useRecord } from '../record-provider'; | ||||
| import { useActionContext } from '../schema-component'; | ||||
| import { useResourceActionContext, useResourceContext } from './ResourceActionProvider'; | ||||
| import { useFilterFieldProps, useFilterFieldOptions } from '../schema-component/antd/filter/useFilterActionProps'; | ||||
| 
 | ||||
| export const useCancelAction = () => { | ||||
|   const form = useForm(); | ||||
| @ -111,7 +112,7 @@ export const useCollectionFilterOptions = (collectionName: string) => { | ||||
|     } | ||||
|     if (nested) { | ||||
|       const targetFields = getCollectionFields(field.target); | ||||
|       const options = getOptions(targetFields, depth+1).filter(Boolean); | ||||
|       const options = getOptions(targetFields, depth + 1).filter(Boolean); | ||||
|       option['children'] = option['children'] || []; | ||||
|       option['children'].push(...options); | ||||
|     } | ||||
| @ -275,7 +276,7 @@ export const useUpdateCollectionActionAndRefreshCM = (options) => { | ||||
|       await refreshCM(); | ||||
|     }, | ||||
|   }; | ||||
| } | ||||
| }; | ||||
| 
 | ||||
| export const useValuesFromRecord = (options) => { | ||||
|   const record = useRecord(); | ||||
| @ -343,3 +344,10 @@ export const useBulkDestroyActionAndRefreshCM = () => { | ||||
|     }, | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| export const useFilterActionProps = () => { | ||||
|   const { collection } = useResourceContext(); | ||||
|   const options = useFilterFieldOptions(collection.fields); | ||||
|   const service = useResourceActionContext(); | ||||
|   return useFilterFieldProps({ options, params: service.params, service }); | ||||
| }; | ||||
|  | ||||
| @ -6,10 +6,15 @@ import { useBlockRequestContext } from '../../../block-provider'; | ||||
| import { useCollection, useCollectionManager } from '../../../collection-manager'; | ||||
| 
 | ||||
| export const useFilterOptions = (collectionName: string) => { | ||||
|   const { getCollectionFields } = useCollectionManager(); | ||||
|   const fields = getCollectionFields(collectionName); | ||||
|   return useFilterFieldOptions(fields); | ||||
| }; | ||||
| 
 | ||||
| export const useFilterFieldOptions = (fields) => { | ||||
|   const fieldSchema = useFieldSchema(); | ||||
|   const nonfilterable = fieldSchema?.['x-component-props']?.nonfilterable || []; | ||||
|   const { getCollectionFields, getInterface } = useCollectionManager(); | ||||
|   const fields = getCollectionFields(collectionName); | ||||
|   const field2option = (field, depth) => { | ||||
|     if (nonfilterable.length && depth === 1 && nonfilterable.includes(field.name)) { | ||||
|       return; | ||||
| @ -44,7 +49,7 @@ export const useFilterOptions = (collectionName: string) => { | ||||
|     } | ||||
|     if (nested) { | ||||
|       const targetFields = getCollectionFields(field.target); | ||||
|       const options = getOptions(targetFields, depth+1).filter(Boolean); | ||||
|       const options = getOptions(targetFields, depth + 1).filter(Boolean); | ||||
|       option['children'] = option['children'] || []; | ||||
|       option['children'].push(...options); | ||||
|     } | ||||
| @ -67,7 +72,7 @@ const isEmpty = (obj) => { | ||||
|   return obj && Object.keys(obj).length === 0 && Object.getPrototypeOf(obj) === Object.prototype; | ||||
| }; | ||||
| 
 | ||||
| const removeNullCondition = (filter) => { | ||||
| export const removeNullCondition = (filter) => { | ||||
|   const items = flat(filter || {}); | ||||
|   const values = {}; | ||||
|   for (const key in items) { | ||||
| @ -96,13 +101,17 @@ export const useFilterActionProps = () => { | ||||
|   const { name } = useCollection(); | ||||
|   const options = useFilterOptions(name); | ||||
|   const { service, props } = useBlockRequestContext(); | ||||
|   const field = useField<Field>(); | ||||
|   return useFilterFieldProps({ options, service, params: props.params }); | ||||
| }; | ||||
| 
 | ||||
| export const useFilterFieldProps = ({ options, service, params }) => { | ||||
|   const { t } = useTranslation(); | ||||
|   const field = useField<Field>(); | ||||
|   return { | ||||
|     options, | ||||
|     onSubmit(values) { | ||||
|       // filter parameter for the block
 | ||||
|       const defaultFilter = removeNullCondition(props.params.filter); | ||||
|       const defaultFilter = removeNullCondition(params.filter); | ||||
|       // filter parameter for the filter action
 | ||||
|       const filter = removeNullCondition(values?.filter); | ||||
|       service.run({ ...service.params?.[0], page: 1, filter: mergeFilter(defaultFilter, filter) }); | ||||
| @ -114,7 +123,7 @@ export const useFilterActionProps = () => { | ||||
|       } | ||||
|     }, | ||||
|     onReset() { | ||||
|       const filter = removeNullCondition(props.params.filter); | ||||
|       const filter = removeNullCondition(params.filter); | ||||
|       service.run({ ...service.params?.[0], filter, page: 1 }); | ||||
|       field.title = t('Filter'); | ||||
|     }, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user