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