diff --git a/packages/client/src/schema-component/antd/calendar/Calendar.tsx b/packages/client/src/schema-component/antd/calendar/Calendar.tsx index fa3977f9e..b9fb7825e 100644 --- a/packages/client/src/schema-component/antd/calendar/Calendar.tsx +++ b/packages/client/src/schema-component/antd/calendar/Calendar.tsx @@ -11,7 +11,6 @@ import { i18n } from '../../../i18n'; import { ActionBar, ActionContext } from '../action'; import { CalendarContext, ToolbarContext } from './context'; import { Event } from './Event'; -import { Filter } from './Filter'; import { Nav } from './Nav'; import './style.less'; import { Title } from './Title'; @@ -182,5 +181,3 @@ Calendar.Today = Today; Calendar.Nav = Nav; Calendar.ViewSelect = ViewSelect; - -Calendar.Filter = Filter; diff --git a/packages/client/src/schema-component/antd/calendar/Filter.tsx b/packages/client/src/schema-component/antd/calendar/Filter.tsx deleted file mode 100644 index 8299b2258..000000000 --- a/packages/client/src/schema-component/antd/calendar/Filter.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { createForm } from '@formily/core'; -import { observer, useFieldSchema } from '@formily/react'; -import flatten from 'flat'; -import React, { useMemo, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { SchemaComponent } from '../../core'; -import { useDesignable } from '../../hooks'; -import { useCompile } from '../../hooks/useCompile'; -import { FilterContext } from '../filter/context'; - -export const Filter = observer((props: any) => { - const { t } = useTranslation(); - const compile = useCompile(); - const { properties } = props; - const { DesignableBar } = useDesignable(); - const filedSchema = useFieldSchema(); - const form = useMemo(() => createForm(), []); - const [visible, setVisible] = useState(false); - const obj = flatten(form.values.filter || {}); - const count = Object.values(obj).filter((i) => (Array.isArray(i) ? i.length : i)).length; - const icon = props.icon || 'FilterOutlined'; - filedSchema.mapProperties((p) => { - properties[p.name] = p; - }); - return ( - - - - ); -}); diff --git a/packages/client/src/schema-component/antd/calendar/index.ts b/packages/client/src/schema-component/antd/calendar/index.ts index 0d52e1336..e82c4290d 100644 --- a/packages/client/src/schema-component/antd/calendar/index.ts +++ b/packages/client/src/schema-component/antd/calendar/index.ts @@ -1,2 +1,3 @@ export * from './Calendar'; export * from './context'; + diff --git a/packages/database/src/__tests__/operator/string-operator.test.ts b/packages/database/src/__tests__/operator/string-operator.test.ts new file mode 100644 index 000000000..b07c00ffb --- /dev/null +++ b/packages/database/src/__tests__/operator/string-operator.test.ts @@ -0,0 +1,42 @@ +import Database, { Collection, mockDatabase } from '@nocobase/database'; + +describe('string operator', () => { + let db: Database; + + let User: Collection; + + afterEach(async () => { + await db.close(); + }); + + beforeEach(async () => { + db = mockDatabase({}); + + await db.clean({ drop: true }); + + User = db.collection({ + name: 'users', + fields: [{ type: 'string', name: 'name' }], + }); + + await db.sync({ + force: true, + }); + }); + + it('should query with include operator', async () => { + const u1 = await db.getRepository('users').create({ + values: { + name: 'names of u1', + }, + }); + + const u1Res = await db.getRepository('users').findOne({ + filter: { + 'name.$includes': 'u1', + }, + }); + + expect(u1Res.get('id')).toEqual(u1.get('id')); + }); +}); diff --git a/packages/database/src/operators/array.ts b/packages/database/src/operators/array.ts index a4292494d..5534eef8c 100644 --- a/packages/database/src/operators/array.ts +++ b/packages/database/src/operators/array.ts @@ -1,4 +1,5 @@ import { Op, Sequelize } from 'sequelize'; +import { isPg, isMySQL } from './utils'; const getFieldName = (ctx) => { const fieldName = ctx.fieldName; @@ -38,18 +39,6 @@ const emptyQuery = (ctx, operator: '=' | '>') => { return `(select ${ifNull}(${funcName}(${fieldName}), 0) ${operator} 0)`; }; -const getDialect = (ctx) => { - return ctx.db.sequelize.getDialect(); -}; - -const isPg = (ctx) => { - return getDialect(ctx) === 'postgres'; -}; - -const isMySQL = (ctx) => { - return getDialect(ctx) === 'mysql'; -}; - export default { $match(value, ctx) { const fieldName = getFieldName(ctx); diff --git a/packages/database/src/operators/index.ts b/packages/database/src/operators/index.ts index a76fc9276..011a19b63 100644 --- a/packages/database/src/operators/index.ts +++ b/packages/database/src/operators/index.ts @@ -3,4 +3,5 @@ export default { ...require('./date').default, ...require('./array').default, ...require('./empty').default, + ...require('./string').default, }; diff --git a/packages/database/src/operators/string.ts b/packages/database/src/operators/string.ts new file mode 100644 index 000000000..a130170cd --- /dev/null +++ b/packages/database/src/operators/string.ts @@ -0,0 +1,40 @@ +import { isPg } from './utils'; +import { Op } from 'sequelize'; + +export default { + $includes(value, ctx) { + return { + [isPg(ctx) ? Op.iLike : Op.like]: `%${value}%`, + }; + }, + + $notIncludes(value, ctx) { + return { + [isPg(ctx) ? Op.notILike : Op.notLike]: `%${value}%`, + }; + }, + + $startsWith(value, ctx) { + return { + [isPg(ctx) ? Op.iLike : Op.like]: `${value}%`, + }; + }, + + $notStartsWith(value, ctx) { + return { + [isPg(ctx) ? Op.notILike : Op.notLike]: `${value}%`, + }; + }, + + $endWith(value, ctx) { + return { + [isPg(ctx) ? Op.iLike : Op.like]: `%${value}`, + }; + }, + + $notEndWith(value, ctx) { + return { + [isPg(ctx) ? Op.notILike : Op.notLike]: `%${value}`, + }; + }, +}; diff --git a/packages/database/src/operators/utils.ts b/packages/database/src/operators/utils.ts new file mode 100644 index 000000000..79c9325d8 --- /dev/null +++ b/packages/database/src/operators/utils.ts @@ -0,0 +1,13 @@ +const getDialect = (ctx) => { + return ctx.db.sequelize.getDialect(); +}; + +const isPg = (ctx) => { + return getDialect(ctx) === 'postgres'; +}; + +const isMySQL = (ctx) => { + return getDialect(ctx) === 'mysql'; +}; + +export { getDialect, isPg, isMySQL };