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