feat: improve field interface filterable parameter

This commit is contained in:
chenos 2022-03-03 15:21:27 +08:00
parent d4bd033917
commit 3ff16e70c0
25 changed files with 254 additions and 136 deletions

View File

@ -27,26 +27,36 @@ export const useCancelFilterAction = () => {
};
export const useCollectionFilterOptions = (collectionName: string) => {
const { getCollection, getInterface } = useCollectionManager();
const options = [];
const collection = getCollection(collectionName);
const fields = collection?.fields || [];
const { getCollectionFields, getInterface } = useCollectionManager();
const fields = getCollectionFields(collectionName);
const field2option = (field) => {
if (!field.interface) {
return;
}
const fieldInterface = getInterface(field.interface);
if (!fieldInterface.operators) {
if (!fieldInterface.filterable) {
return;
}
const { nested, children, operators } = fieldInterface.filterable;
const option = {
name: field.name,
title: field?.uiSchema?.title || field.name,
schema: field?.uiSchema,
operators: fieldInterface.operators || [],
operators: operators || [],
};
if (children?.length) {
option['children'] = children;
}
if (nested) {
const targetFields = getCollectionFields(field.target);
const options = getOptions(targetFields);
option['children'] = option['children'] || [];
option['children'].push(...options);
}
return option;
};
const getOptions = (fields) => {
const options = [];
fields.forEach((field) => {
const option = field2option(field);
if (option) {
@ -54,6 +64,8 @@ export const useCollectionFilterOptions = (collectionName: string) => {
}
});
return options;
};
return getOptions(fields);
};
export const useFilterDataSource = (options) => {

View File

@ -15,6 +15,10 @@ export const useCollectionManager = () => {
getCollection(name: string) {
return collections?.find((collection) => collection.name === name);
},
getCollectionFields(name: string) {
const collection = collections?.find((collection) => collection.name === name);
return collection?.fields || [];
},
getInterface(name: string) {
return interfaces[name] ? clone(interfaces[name]) : null;
},

View File

@ -48,4 +48,21 @@ export const attachment: IField = {
default: true,
},
},
filterable: {
children: [
{
name: 'filename',
title: '{{t("Filename")}}',
operators: [
{ label: 'empty', value: '$empty' },
{ label: 'notEmpty', value: '$notEmpty' },
],
schema: {
title: '{{t("Filename")}}',
type: 'string',
'x-component': 'Input',
},
},
],
},
};

View File

@ -1,4 +1,4 @@
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const checkbox: IField = {
@ -18,8 +18,7 @@ export const checkbox: IField = {
properties: {
...defaultProps,
},
operators: [
{ label: '{{t("Yes")}}', value: '$isTruly', selected: true, noValue: true },
{ label: '{{t("No")}}', value: '$isFalsy', noValue: true },
],
filterable: {
operators: operators.boolean,
},
};

View File

@ -1,4 +1,4 @@
import { dataSource, defaultProps } from './properties';
import { dataSource, defaultProps, operators } from './properties';
import { IField } from './types';
export const checkboxGroup: IField = {
@ -20,4 +20,7 @@ export const checkboxGroup: IField = {
...defaultProps,
'uiSchema.enum': dataSource,
},
filterable: {
operators: operators.array,
},
};

View File

@ -1,5 +1,5 @@
import { uid } from '@formily/shared';
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const chinaRegion: IField = {
@ -74,5 +74,18 @@ export const chinaRegion: IField = {
'x-decorator': 'FormItem',
},
},
operators: [{ label: '{{t("is")}}', value: 'code.$in' }],
filterable: {
children: [
{
name: 'name',
title: '名称',
operators: operators.string,
schema: {
title: '名称',
type: 'string',
'x-component': 'Input',
},
},
],
},
};

View File

@ -1,4 +1,4 @@
import { dateTimeProps, defaultProps } from './properties';
import { dateTimeProps, defaultProps, operators } from './properties';
import { IField } from './types';
export const createdAt: IField = {
@ -24,4 +24,7 @@ export const createdAt: IField = {
...defaultProps,
...dateTimeProps,
},
filterable: {
operators: operators.datetime,
},
};

View File

@ -1,4 +1,4 @@
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const createdBy: IField = {
@ -29,4 +29,18 @@ export const createdBy: IField = {
properties: {
...defaultProps,
},
filterable: {
children: [
{
name: 'nickname',
title: '{{t("Nickname")}}',
operators: operators.string,
schema: {
title: '{{t("Nickname")}}',
type: 'string',
'x-component': 'Input',
},
},
],
},
};

View File

@ -1,4 +1,4 @@
import { dateTimeProps, defaultProps } from './properties';
import { dateTimeProps, defaultProps, operators } from './properties';
import { IField } from './types';
export const datetime: IField = {
@ -24,14 +24,7 @@ export const datetime: IField = {
...defaultProps,
...dateTimeProps,
},
operators: [
{ label: "{{ t('is') }}", value: '$dateOn', selected: true },
{ label: "{{ t('is not') }}", value: '$dateNotOn' },
{ label: "{{ t('is before') }}", value: '$dateBefore' },
{ label: "{{ t('is after') }}", value: '$dateAfter' },
{ label: "{{ t('is on or after') }}", value: '$dateNotBefore' },
{ label: "{{ t('is on or before') }}", value: '$dateNotAfter' },
{ label: "{{ t('is empty') }}", value: '$null', noValue: true },
{ label: "{{ t('is not empty') }}", value: '$notNull', noValue: true },
],
filterable: {
operators: operators.datetime,
},
};

View File

@ -1,5 +1,4 @@
import { input } from './input';
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const email: IField = {
@ -22,5 +21,7 @@ export const email: IField = {
properties: {
...defaultProps,
},
operators: input.operators,
filterable: {
operators: operators.string,
},
};

View File

@ -1,4 +1,4 @@
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const input: IField = {
@ -19,12 +19,7 @@ export const input: IField = {
properties: {
...defaultProps,
},
operators: [
{ label: '{{t("contains")}}', value: '$includes', selected: true },
{ label: '{{t("does not contain")}}', value: '$notIncludes' },
{ label: '{{t("is")}}', value: '$eq' },
{ label: '{{t("is not")}}', value: '$ne' },
{ label: '{{t("is empty")}}', value: '$empty', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
],
filterable: {
operators: operators.string,
},
};

View File

@ -69,4 +69,7 @@ export const linkTo: IField = {
'x-component': 'Checkbox',
},
},
filterable: {
nested: true,
},
};

View File

@ -1,4 +1,4 @@
import { dataSource, defaultProps } from './properties';
import { dataSource, defaultProps, operators } from './properties';
import { IField } from './types';
export const multipleSelect: IField = {
@ -26,29 +26,7 @@ export const multipleSelect: IField = {
...defaultProps,
'uiSchema.enum': dataSource,
},
operators: [
{
label: '{{t("is")}}',
value: '$match',
selected: true,
schema: { 'x-component': 'Select' },
filterable: {
operators: operators.array,
},
{
label: '{{t("is not")}}',
value: '$notMatch',
schema: { 'x-component': 'Select' },
},
{
label: '{{t("contains")}}',
value: '$anyOf',
schema: { 'x-component': 'Select' },
},
{
label: '{{t("does not contain")}}',
value: '$noneOf',
schema: { 'x-component': 'Select' },
},
{ label: '{{t("is empty")}}', value: '$empty', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
],
};

View File

@ -1,4 +1,4 @@
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const number: IField = {
@ -39,14 +39,7 @@ export const number: IField = {
],
},
},
operations: [
{ label: '{{t("=")}}', value: '$eq', selected: true },
{ label: '{{t("≠")}}', value: '$ne' },
{ label: '{{t(">")}}', value: '$gt' },
{ label: '{{t("≥")}}', value: '$gte' },
{ label: '{{t("<")}}', value: '$lt' },
{ label: '{{t("≤")}}', value: '$lte' },
{ label: '{{t("is empty")}}', value: '$null', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notNull', noValue: true },
],
filterable: {
operators: operators.number,
},
};

View File

@ -1,5 +1,4 @@
import { number } from './number';
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const percent: IField = {
@ -43,5 +42,7 @@ export const percent: IField = {
],
},
},
operators: number.operators,
filterable: {
operators: operators.number,
},
};

View File

@ -1,5 +1,4 @@
import { input } from './input';
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const phone: IField = {
@ -24,5 +23,7 @@ export const phone: IField = {
properties: {
...defaultProps,
},
operators: input.operators,
filterable: {
operators: operators.string,
},
};

View File

@ -196,3 +196,6 @@ export const defaultProps = {
},
type,
};
export * as operators from './operators';

View File

@ -0,0 +1,100 @@
export const string = [
{ label: '{{t("contains")}}', value: '$includes', selected: true },
{ label: '{{t("does not contain")}}', value: '$notIncludes' },
{ label: '{{t("is")}}', value: '$eq' },
{ label: '{{t("is not")}}', value: '$ne' },
{ label: '{{t("is empty")}}', value: '$empty', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
];
export const array = [
{
label: '{{t("is")}}',
value: '$match',
selected: true,
schema: { 'x-component': 'Select' },
},
{
label: '{{t("is not")}}',
value: '$notMatch',
schema: { 'x-component': 'Select' },
},
{
label: '{{t("contains")}}',
value: '$anyOf',
schema: { 'x-component': 'Select' },
},
{
label: '{{t("does not contain")}}',
value: '$noneOf',
schema: { 'x-component': 'Select' },
},
{ label: '{{t("is empty")}}', value: '$empty', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
];
export const datetime = [
{ label: "{{ t('is') }}", value: '$dateOn', selected: true },
{ label: "{{ t('is not') }}", value: '$dateNotOn' },
{ label: "{{ t('is before') }}", value: '$dateBefore' },
{ label: "{{ t('is after') }}", value: '$dateAfter' },
{ label: "{{ t('is on or after') }}", value: '$dateNotBefore' },
{ label: "{{ t('is on or before') }}", value: '$dateNotAfter' },
{ label: "{{ t('is empty') }}", value: '$null', noValue: true },
{ label: "{{ t('is not empty') }}", value: '$notNull', noValue: true },
];
export const number = [
{ label: '{{t("=")}}', value: '$eq', selected: true },
{ label: '{{t("≠")}}', value: '$ne' },
{ label: '{{t(">")}}', value: '$gt' },
{ label: '{{t("≥")}}', value: '$gte' },
{ label: '{{t("<")}}', value: '$lt' },
{ label: '{{t("≤")}}', value: '$lte' },
{ label: '{{t("is empty")}}', value: '$empty', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
];
export const enumType = [
{
label: '{{t("is")}}',
value: '$eq',
selected: true,
schema: { 'x-component': 'Select' },
},
{
label: '{{t("is not")}}',
value: '$ne',
schema: { 'x-component': 'Select' },
},
{
label: '{{t("contains")}}',
value: '$in',
schema: {
'x-component': 'Select',
'x-component-props': { mode: 'tags' },
},
},
{
label: '{{t("does not contain")}}',
value: '$notIn',
schema: {
'x-component': 'Select',
'x-component-props': { mode: 'tags' },
},
},
{ label: '{{t("is empty")}}', value: '$empty', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
];
export const time = [
{ label: '{{t("is")}}', value: '$eq', selected: true },
{ label: '{{t("is not")}}', value: '$neq' },
{ label: '{{t("is empty")}}', value: '$null', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notNull', noValue: true },
];
export const boolean = [
{ label: '{{t("Yes")}}', value: '$isTruly', selected: true, noValue: true },
{ label: '{{t("No")}}', value: '$isFalsy', noValue: true },
];

View File

@ -1,5 +1,4 @@
import { dataSource, defaultProps } from './properties';
import { select } from './select';
import { dataSource, defaultProps, operators } from './properties';
import { IField } from './types';
export const radioGroup: IField = {
@ -21,5 +20,7 @@ export const radioGroup: IField = {
...defaultProps,
'uiSchema.enum': dataSource,
},
operators: select.operators,
filterable: {
operators: operators.enumType,
},
};

View File

@ -1,4 +1,4 @@
import { dataSource, defaultProps } from './properties';
import { dataSource, defaultProps, operators } from './properties';
import { IField } from './types';
export const select: IField = {
@ -21,35 +21,7 @@ export const select: IField = {
...defaultProps,
'uiSchema.enum': dataSource,
},
operators: [
{
label: '{{t("is")}}',
value: '$eq',
selected: true,
schema: { 'x-component': 'Select' },
filterable: {
operators: operators.enumType,
},
{
label: '{{t("is not")}}',
value: '$ne',
schema: { 'x-component': 'Select' },
},
{
label: '{{t("contains")}}',
value: '$in',
schema: {
'x-component': 'Select',
'x-component-props': { mode: 'tags' },
},
},
{
label: '{{t("does not contain")}}',
value: '$notIn',
schema: {
'x-component': 'Select',
'x-component-props': { mode: 'tags' },
},
},
{ label: '{{t("is empty")}}', value: '$empty', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notEmpty', noValue: true },
],
};

View File

@ -9,7 +9,6 @@ export const subTable: IField = {
order: 2,
title: '{{t("Sub-table")}}',
isAssociation: true,
disabled: true,
default: {
type: 'hasMany',
// name,

View File

@ -1,4 +1,4 @@
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const time: IField = {
@ -36,10 +36,7 @@ export const time: IField = {
],
},
},
operators: [
{ label: '{{t("is")}}', value: '$eq', selected: true },
{ label: '{{t("is not")}}', value: '$neq' },
{ label: '{{t("is empty")}}', value: '$null', noValue: true },
{ label: '{{t("is not empty")}}', value: '$notNull', noValue: true },
],
filterable: {
operators: operators.time,
},
};

View File

@ -9,5 +9,6 @@ interface IDefault {
export interface IField extends ISchema {
default?: IDefault;
operators?: any[];
filterable?: any,
[key: string]: any;
}

View File

@ -1,5 +1,4 @@
import { datetime } from './datetime';
import { dateTimeProps, defaultProps } from './properties';
import { dateTimeProps, defaultProps, operators } from './properties';
import { IField } from './types';
export const updatedAt: IField = {
@ -25,5 +24,7 @@ export const updatedAt: IField = {
...defaultProps,
...dateTimeProps,
},
operators: datetime.operators,
filterable: {
operators: operators.datetime,
},
};

View File

@ -1,4 +1,4 @@
import { defaultProps } from './properties';
import { defaultProps, operators } from './properties';
import { IField } from './types';
export const updatedBy: IField = {
@ -28,4 +28,18 @@ export const updatedBy: IField = {
properties: {
...defaultProps,
},
filterable: {
children: [
{
name: 'nickname',
title: '{{t("Nickname")}}',
operators: operators.string,
schema: {
title: '{{t("Nickname")}}',
type: 'string',
'x-component': 'Input',
},
},
],
},
};