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:
katherinehhh 2022-10-24 09:49:16 +08:00 committed by GitHub
parent 40554d8151
commit 2c690a39e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 35 deletions

View File

@ -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 (
<div>
<SchemaComponent
schema={collectionSchema}
components={{
AddSubFieldAction,
EditSubFieldAction,
FieldSummary,
}}
scope={{
useDestroySubField,
useBulkDestroySubField,
useSelectedRowKeys,
useCollectionValues,
useAsyncDataSource,
loadCollections,
useCurrentFields,
useNewId,
}}
/>
<SchemaComponentContext.Provider value={{ ...ctx, designable: false }}>
<SchemaComponent
schema={collectionSchema}
components={{
AddSubFieldAction,
EditSubFieldAction,
FieldSummary,
}}
scope={{
useDestroySubField,
useBulkDestroySubField,
useSelectedRowKeys,
useCollectionValues,
useAsyncDataSource,
loadCollections,
useCurrentFields,
useNewId,
}}
/>
</SchemaComponentContext.Provider>
</div>
);
};

View File

@ -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") }}',

View File

@ -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 });
};

View File

@ -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');
},