From 2c690a39e062863999aa0820fcce5bec15daa444 Mon Sep 17 00:00:00 2001 From: katherinehhh Date: Mon, 24 Oct 2022 09:49:16 +0800 Subject: [PATCH] feat: add filter action to collection table (#953) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 数据表支持筛选 * feat: 数据表支持筛选 * feat: 数据表支持筛选 * feat: 数据表支持筛选 * fix: format code Co-authored-by: chenos --- .../Configuration/ConfigurationTable.tsx | 45 ++++++++++--------- .../Configuration/schemas/collections.ts | 21 +++++++-- .../src/collection-manager/action-hooks.ts | 18 +++++--- .../antd/filter/useFilterActionProps.ts | 21 ++++++--- 4 files changed, 70 insertions(+), 35 deletions(-) diff --git a/packages/core/client/src/collection-manager/Configuration/ConfigurationTable.tsx b/packages/core/client/src/collection-manager/Configuration/ConfigurationTable.tsx index b37945355..69d1d72c2 100644 --- a/packages/core/client/src/collection-manager/Configuration/ConfigurationTable.tsx +++ b/packages/core/client/src/collection-manager/Configuration/ConfigurationTable.tsx @@ -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,26 +179,29 @@ export const ConfigurationTable = () => { value: item.name, })); }; + const ctx = useContext(SchemaComponentContext); return (
- + + +
); }; diff --git a/packages/core/client/src/collection-manager/Configuration/schemas/collections.ts b/packages/core/client/src/collection-manager/Configuration/schemas/collections.ts index 3f7b8e032..f80ed6380 100644 --- a/packages/core/client/src/collection-manager/Configuration/schemas/collections.ts +++ b/packages/core/client/src/collection-manager/Configuration/schemas/collections.ts @@ -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") }}', diff --git a/packages/core/client/src/collection-manager/action-hooks.ts b/packages/core/client/src/collection-manager/action-hooks.ts index 81b7a8d2f..d73b79e80 100644 --- a/packages/core/client/src/collection-manager/action-hooks.ts +++ b/packages/core/client/src/collection-manager/action-hooks.ts @@ -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(); @@ -305,7 +306,7 @@ export const useCreateActionAndRefreshCM = () => { const { refreshCM } = useCollectionManager(); return { async run() { - await run(); + await run(); await refreshCM(); }, }; @@ -337,9 +338,16 @@ export const useBulkDestroyActionAndRefreshCM = () => { const { run } = useBulkDestroyAction(); const { refreshCM } = useCollectionManager(); return { - async run() { + async run() { await run(); await refreshCM(); }, }; }; + +export const useFilterActionProps = () => { + const { collection } = useResourceContext(); + const options = useFilterFieldOptions(collection.fields); + const service = useResourceActionContext(); + return useFilterFieldProps({ options, params: service.params, service }); +}; diff --git a/packages/core/client/src/schema-component/antd/filter/useFilterActionProps.ts b/packages/core/client/src/schema-component/antd/filter/useFilterActionProps.ts index 74f25e3df..3b819979a 100644 --- a/packages/core/client/src/schema-component/antd/filter/useFilterActionProps.ts +++ b/packages/core/client/src/schema-component/antd/filter/useFilterActionProps.ts @@ -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(); + return useFilterFieldProps({ options, service, params: props.params }); +}; + +export const useFilterFieldProps = ({ options, service, params }) => { const { t } = useTranslation(); + const field = useField(); 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'); },