feat(variable): add current role (#3167)
* feat(variable): add current role * chore: translate * feat: parsing in the backend * fix: fix tests
This commit is contained in:
parent
d782776a8d
commit
a2be1a0e33
@ -606,6 +606,7 @@
|
||||
"Constant value": "Constant value",
|
||||
"Dynamic value": "Dynamic value",
|
||||
"Current user": "Current user",
|
||||
"Current role": "Current role",
|
||||
"Current record": "Current record",
|
||||
"Parent record": "Parent record",
|
||||
"Current time": "Current time",
|
||||
|
@ -602,6 +602,7 @@
|
||||
"Constant value": "Valor constante",
|
||||
"Dynamic value": "Valor dinámico",
|
||||
"Current user": "Usuario actual",
|
||||
"Current role": "Rol actual",
|
||||
"Current record": "Registro actual",
|
||||
"Parent record": "Registro padre",
|
||||
"Current time": "Hora actual",
|
||||
|
@ -599,6 +599,7 @@
|
||||
"Constant value": "Valeur constante",
|
||||
"Dynamic value": "Valeur dynamique",
|
||||
"Current user": "Utilisateur actuel",
|
||||
"Current role": "Rôle actuel",
|
||||
"Current record": "Enregistrement actuel",
|
||||
"Parent record": "Enregistrement parent",
|
||||
"Current time": "Heure actuelle",
|
||||
|
@ -501,6 +501,7 @@
|
||||
"Constant value": "定数値",
|
||||
"Dynamic value": "動的値",
|
||||
"Current user": "現在のユーザー",
|
||||
"Current role": "現在の役割",
|
||||
"Current record": "現在のレコード",
|
||||
"Popup close method": "ポップアップを閉じる方法",
|
||||
"Automatic close": "自動で閉じる",
|
||||
|
@ -438,6 +438,7 @@
|
||||
"Constant value": "Постоянное значение",
|
||||
"Dynamic value": "Динамическое значение",
|
||||
"Current user": "Текущий пользователь",
|
||||
"Current role": "Текущая роль",
|
||||
"Current record": "Текущая запись",
|
||||
"Parent record": "Родительская запись",
|
||||
"Popup close method": "Метод закрытия всплывающего окна",
|
||||
|
@ -437,6 +437,7 @@
|
||||
"Constant value": "Sabit değer",
|
||||
"Dynamic value": "Dinamik değer",
|
||||
"Current user": "Seçili kullanıcı",
|
||||
"Current role": "Seçili rol",
|
||||
"Current record": "Seçili kayıt",
|
||||
"Parent record": "Üst kayıt",
|
||||
"Popup close method": "Açılır pencere kapatma metodu",
|
||||
|
@ -619,6 +619,7 @@
|
||||
"Constant value": "Константне значення",
|
||||
"Dynamic value": "Динамічне значення",
|
||||
"Current user": "Поточний користувач",
|
||||
"Current role": "Поточна роль",
|
||||
"Current record": "Поточний запис",
|
||||
"Parent record": "Батьківський запис",
|
||||
"Current time": "Поточний час",
|
||||
|
@ -622,6 +622,7 @@
|
||||
"Constant value": "静态值",
|
||||
"Dynamic value": "动态值",
|
||||
"Current user": "当前用户",
|
||||
"Current role": "当前角色",
|
||||
"Current record": "当前记录",
|
||||
"Parent record": "上级记录",
|
||||
"Current time": "当前时间",
|
||||
|
@ -146,6 +146,10 @@ export const getShouldChange = ({
|
||||
const collectionsInheritChain = collectionField ? getAllCollectionsInheritChain(collectionField.target) : [];
|
||||
|
||||
return async (value: any, optionPath: any[]) => {
|
||||
if (_.isString(value) && value.includes('$nRole')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isVariable(value) || !variables || !collectionField) {
|
||||
return true;
|
||||
}
|
||||
|
@ -49,6 +49,10 @@ interface BaseProps {
|
||||
* 不需要禁用选项,一般会在表达式中使用
|
||||
*/
|
||||
noDisabled?: boolean;
|
||||
/**
|
||||
* 不需要二级菜单
|
||||
*/
|
||||
noChildren?: boolean;
|
||||
/**
|
||||
* 对每一个关系字段的 fields 进行过滤
|
||||
* @param fields
|
||||
@ -131,6 +135,7 @@ export const useBaseVariable = ({
|
||||
name,
|
||||
title,
|
||||
collectionName,
|
||||
noChildren = false,
|
||||
// TODO: 等整理完完整测试用例后,再开启该功能
|
||||
noDisabled = true,
|
||||
returnFields = (fields) => fields,
|
||||
@ -202,7 +207,7 @@ export const useBaseVariable = ({
|
||||
label: title,
|
||||
value: name,
|
||||
key: name,
|
||||
isLeaf: false,
|
||||
isLeaf: noChildren,
|
||||
field: {
|
||||
target: collectionName,
|
||||
},
|
||||
|
@ -0,0 +1,39 @@
|
||||
import { Schema } from '@formily/json-schema';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { CollectionFieldOptions } from '../../../collection-manager';
|
||||
import { useBaseVariable } from './useBaseVariable';
|
||||
|
||||
/**
|
||||
* 变量:`当前角色`
|
||||
* @param param0
|
||||
* @returns
|
||||
*/
|
||||
export const useRoleVariable = ({
|
||||
collectionField,
|
||||
uiSchema,
|
||||
noDisabled,
|
||||
targetFieldSchema,
|
||||
maxDepth = 0,
|
||||
}: {
|
||||
collectionField: CollectionFieldOptions;
|
||||
uiSchema: any;
|
||||
maxDepth?: number;
|
||||
noDisabled?: boolean;
|
||||
/** 消费变量值的字段 */
|
||||
targetFieldSchema?: Schema;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const result = useBaseVariable({
|
||||
collectionField,
|
||||
uiSchema,
|
||||
maxDepth,
|
||||
name: '$nRole',
|
||||
title: t('Current role'),
|
||||
collectionName: 'roles',
|
||||
noDisabled,
|
||||
targetFieldSchema,
|
||||
noChildren: true,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
@ -10,6 +10,7 @@ import { useFormVariable } from './useFormVariable';
|
||||
import { useIterationVariable } from './useIterationVariable';
|
||||
import { useParentRecordVariable } from './useParentRecordVariable';
|
||||
import { useRecordVariable } from './useRecordVariable';
|
||||
import { useRoleVariable } from './useRoleVariable';
|
||||
import { useUserVariable } from './useUserVariable';
|
||||
|
||||
interface Props {
|
||||
@ -58,6 +59,12 @@ export const useVariableOptions = ({
|
||||
noDisabled,
|
||||
targetFieldSchema,
|
||||
});
|
||||
const roleVariable = useRoleVariable({
|
||||
uiSchema: uiSchema,
|
||||
collectionField,
|
||||
noDisabled,
|
||||
targetFieldSchema,
|
||||
});
|
||||
const dateVariable = useDateVariable({ operator, schema: uiSchema, noDisabled });
|
||||
const formVariable = useFormVariable({
|
||||
schema: uiSchema,
|
||||
@ -91,6 +98,7 @@ export const useVariableOptions = ({
|
||||
return useMemo(() => {
|
||||
return [
|
||||
userVariable,
|
||||
roleVariable,
|
||||
dateVariable,
|
||||
form && !form.readPretty && formVariable,
|
||||
(isInSubForm || isInSubTable) && iterationVariable,
|
||||
@ -101,6 +109,7 @@ export const useVariableOptions = ({
|
||||
].filter(Boolean);
|
||||
}, [
|
||||
userVariable,
|
||||
roleVariable,
|
||||
dateVariable,
|
||||
form,
|
||||
formVariable,
|
||||
|
@ -14,7 +14,7 @@ interface Props {
|
||||
}
|
||||
|
||||
// TODO: 建议变量名统一命名为 `$n` 开头,以防止与 formily 内置变量冲突
|
||||
const defaultExclude = ['$user', '$date', '$nDate'];
|
||||
const defaultExclude = ['$user', '$date', '$nDate', '$nRole'];
|
||||
|
||||
const useParseDataScopeFilter = ({ exclude = defaultExclude, currentRecord }: Props = {}) => {
|
||||
const localVariables = useLocalVariables({ currentRecord });
|
||||
|
@ -56,6 +56,10 @@ vi.mock('../../collection-manager', async () => {
|
||||
});
|
||||
|
||||
const { apiClient, mockRequest } = mockAPIClient();
|
||||
|
||||
// 用于解析 `$nRole` 的值
|
||||
apiClient.auth.role = 'root';
|
||||
|
||||
mockRequest.onGet('/auth:check').reply(() => {
|
||||
return [
|
||||
200,
|
||||
@ -67,6 +71,16 @@ mockRequest.onGet('/auth:check').reply(() => {
|
||||
},
|
||||
];
|
||||
});
|
||||
mockRequest.onGet('/roles:check').reply(() => {
|
||||
return [
|
||||
200,
|
||||
{
|
||||
data: {
|
||||
role: 'root',
|
||||
},
|
||||
},
|
||||
];
|
||||
});
|
||||
mockRequest.onGet('/users/0/belongsToField:get').reply(() => {
|
||||
return [
|
||||
200,
|
||||
@ -194,6 +208,7 @@ describe('useVariables', () => {
|
||||
"tomorrow": [Function],
|
||||
"yesterday": [Function],
|
||||
},
|
||||
"$nRole": "root",
|
||||
"$system": {
|
||||
"now": [Function],
|
||||
},
|
||||
@ -404,6 +419,7 @@ describe('useVariables', () => {
|
||||
"tomorrow": [Function],
|
||||
"yesterday": [Function],
|
||||
},
|
||||
"$nRole": "root",
|
||||
"$system": {
|
||||
"now": [Function],
|
||||
},
|
||||
@ -487,6 +503,7 @@ describe('useVariables', () => {
|
||||
"tomorrow": [Function],
|
||||
"yesterday": [Function],
|
||||
},
|
||||
"$nRole": "root",
|
||||
"$new": {
|
||||
"name": "new variable",
|
||||
},
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { dayjs } from '@nocobase/utils/client';
|
||||
import { useMemo } from 'react';
|
||||
import { useAPIClient } from '../../api-client';
|
||||
import { getDateRanges } from '../../schema-component/antd/date-picker/util';
|
||||
import { useCurrentUserContext } from '../../user';
|
||||
import { VariableOption } from '../types';
|
||||
|
||||
const useBuiltInVariables = () => {
|
||||
const data = useCurrentUserContext();
|
||||
const apiClient = useAPIClient();
|
||||
|
||||
const currentUser = data?.data?.data;
|
||||
const dateVars = getDateRanges();
|
||||
@ -16,6 +18,11 @@ const useBuiltInVariables = () => {
|
||||
ctx: currentUser,
|
||||
collectionName: 'users',
|
||||
},
|
||||
{
|
||||
name: '$nRole',
|
||||
ctx: apiClient.auth?.role,
|
||||
collectionName: 'roles',
|
||||
},
|
||||
/**
|
||||
* @deprecated
|
||||
* 兼容老版本
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { getDateVars, parseFilter } from '@nocobase/utils';
|
||||
import lodash from 'lodash';
|
||||
|
||||
function getUser(ctx) {
|
||||
return async ({ fields }) => {
|
||||
@ -54,6 +53,7 @@ export const parseVariables = async (ctx, next) => {
|
||||
// 新的命名方式,防止和 formily 内置变量冲突
|
||||
$nDate: getDateVars(),
|
||||
$user: getUser(ctx),
|
||||
$nRole: ctx.state.currentRole,
|
||||
},
|
||||
});
|
||||
await next();
|
||||
|
Loading…
Reference in New Issue
Block a user