feat: filter with variable ()

This commit is contained in:
chenos 2022-07-04 17:50:18 +08:00 committed by GitHub
parent ec7bc2bc8b
commit e3b6c0513a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 76 additions and 6 deletions
packages
core
acl/src
client/src
collection-manager/interfaces/properties
schema-component/antd/filter
plugins/users

View File

@ -1,12 +1,12 @@
import { Action } from '@nocobase/resourcer';
import EventEmitter from 'events';
import parse from 'json-templates';
import compose from 'koa-compose';
import lodash from 'lodash';
import { AclAvailableAction, AvailableActionOptions } from './acl-available-action';
import { ACLAvailableStrategy, AvailableStrategyOptions, predicate } from './acl-available-strategy';
import { ACLRole, RoleActionParams } from './acl-role';
import { AllowManager } from './allow-manager';
const parse = require('json-templates');
interface CanResult {
role: string;

View File

@ -70,6 +70,14 @@ export const number = [
export const id = [
{ label: '{{t("is")}}', value: '$eq', selected: true },
{ label: '{{t("is not")}}', value: '$ne' },
{
label: '{{t("is variable")}}',
value: '$isVar',
schema: {
'x-component': 'VariableCascader',
'x-component-props': {},
},
},
{
label: '{{t("is current logged-in user")}}',
value: '$isCurrentUser',

View File

@ -1,10 +1,52 @@
import { createForm, onFieldValueChange } from '@formily/core';
import { FieldContext, FormContext } from '@formily/react';
import { connect, FieldContext, FormContext } from '@formily/react';
import { merge } from '@formily/shared';
import { Cascader } from 'antd';
import React, { useContext, useMemo } from 'react';
import { SchemaComponent } from '../../core';
import { useComponent } from '../../hooks';
import { useCompile, useComponent } from '../../hooks';
import { FilterContext } from './context';
import { useFilterOptions } from './useFilterActionProps';
const VariableCascader = connect((props) => {
const fields = useFilterOptions('users');
const compile = useCompile();
const { value, onChange } = props;
return (
<Cascader
value={value ? value.split('.') : []}
fieldNames={{
label: 'title',
value: 'name',
children: 'children',
}}
onChange={(value) => {
onChange(value ? value.join('.') : null);
}}
options={compile([
{
title: '{{t("Current user")}}',
name: 'currentUser',
children: fields
.filter((field) => {
if (!field.target) {
return true;
}
return field.type === 'belongsTo';
})
.map((field) => {
if (field.children) {
field.children = field.children.filter((child) => {
return !child.target;
});
}
return field;
}),
},
])}
/>
);
});
export const DynamicComponent = (props) => {
const { dynamicComponent } = useContext(FilterContext);
@ -38,6 +80,9 @@ export const DynamicComponent = (props) => {
'x-validator': undefined,
'x-decorator': undefined,
}}
components={{
VariableCascader,
}}
/>
</FieldContext.Provider>
);

View File

@ -24,6 +24,8 @@ export const useFilterOptions = (collectionName: string) => {
const { nested, children, operators } = fieldInterface.filterable;
const option = {
name: field.name,
type: field.type,
target: field.target,
title: field?.uiSchema?.title || field.name,
schema: field?.uiSchema,
operators:

View File

@ -14,7 +14,8 @@
},
"devDependencies": {
"@nocobase/test": "0.7.1-alpha.7",
"@types/jsonwebtoken": "^8.5.8"
"@types/jsonwebtoken": "^8.5.8",
"json-templates": "^4.2.0"
},
"gitHead": "7e9556e489007577fc0ed89063b3a9ce2f9aae53"
}

View File

@ -5,6 +5,7 @@ export function parseToken(options?: { plugin: UsersPlugin }) {
return async function parseToken(ctx: Context, next: Next) {
const user = await findUserByToken(ctx, options.plugin);
if (user) {
console.log('appends', user.toJSON());
ctx.state.currentUser = user;
setCurrentRole(ctx);
}
@ -45,12 +46,18 @@ async function findUserByToken(ctx: Context, plugin: UsersPlugin) {
try {
const { userId } = await plugin.jwtService.decode(token);
const collection = ctx.db.getCollection('users');
const appends = ['roles'];
for (const [, field] of collection.fields) {
if (field.type === 'belongsTo') {
appends.push(field.name);
}
}
return await ctx.db.getRepository('users').findOne({
appends,
filter: {
id: userId,
},
appends: ['roles'],
});
} catch (error) {
return null;

View File

@ -1,5 +1,6 @@
import { Collection, Op } from '@nocobase/database';
import { Plugin } from '@nocobase/server';
import parse from 'json-templates';
import { resolve } from 'path';
import { namespace } from './';
import * as actions from './actions/users';
@ -35,6 +36,12 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
[Op.eq]: ctx?.app?.ctx?.state?.currentUser?.id || -1,
};
},
$isVar(val, ctx) {
const obj = parse({ val: `{{${val}}}` })(JSON.parse(JSON.stringify(ctx?.app?.ctx?.state)));
return {
[Op.eq]: obj.val,
};
},
});
this.db.registerModels({ UserModel });
this.db.on('users.afterCreateWithAssociations', async (model, options) => {