feat: improve field interface filterable parameter
This commit is contained in:
parent
d4bd033917
commit
3ff16e70c0
@ -27,33 +27,45 @@ 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;
|
||||
};
|
||||
fields.forEach((field) => {
|
||||
const option = field2option(field);
|
||||
if (option) {
|
||||
options.push(option);
|
||||
}
|
||||
});
|
||||
return options;
|
||||
const getOptions = (fields) => {
|
||||
const options = [];
|
||||
fields.forEach((field) => {
|
||||
const option = field2option(field);
|
||||
if (option) {
|
||||
options.push(option);
|
||||
}
|
||||
});
|
||||
return options;
|
||||
};
|
||||
return getOptions(fields);
|
||||
};
|
||||
|
||||
export const useFilterDataSource = (options) => {
|
||||
|
@ -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;
|
||||
},
|
||||
|
@ -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',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -69,4 +69,7 @@ export const linkTo: IField = {
|
||||
'x-component': 'Checkbox',
|
||||
},
|
||||
},
|
||||
filterable: {
|
||||
nested: true,
|
||||
},
|
||||
};
|
||||
|
@ -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' },
|
||||
},
|
||||
{
|
||||
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 },
|
||||
],
|
||||
filterable: {
|
||||
operators: operators.array,
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -196,3 +196,6 @@ export const defaultProps = {
|
||||
},
|
||||
type,
|
||||
};
|
||||
|
||||
|
||||
export * as operators from './operators';
|
||||
|
@ -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 },
|
||||
];
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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' },
|
||||
},
|
||||
{
|
||||
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 },
|
||||
],
|
||||
filterable: {
|
||||
operators: operators.enumType,
|
||||
},
|
||||
};
|
||||
|
@ -9,7 +9,6 @@ export const subTable: IField = {
|
||||
order: 2,
|
||||
title: '{{t("Sub-table")}}',
|
||||
isAssociation: true,
|
||||
disabled: true,
|
||||
default: {
|
||||
type: 'hasMany',
|
||||
// name,
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -9,5 +9,6 @@ interface IDefault {
|
||||
export interface IField extends ISchema {
|
||||
default?: IDefault;
|
||||
operators?: any[];
|
||||
filterable?: any,
|
||||
[key: string]: any;
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
@ -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',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user