mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 21:49:25 +08:00
feat: support extending frontend filter operators (#6085)
* feat: operator extension * fix: bug * refactor: code improve * fix: jsonLogic --------- Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
3df4c0944d
commit
583ef1b98a
@ -2,9 +2,7 @@
|
|||||||
"version": "1.6.0-alpha.25",
|
"version": "1.6.0-alpha.25",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"useWorkspaces": true,
|
"useWorkspaces": true,
|
||||||
"npmClientArgs": [
|
"npmClientArgs": ["--ignore-engines"],
|
||||||
"--ignore-engines"
|
|
||||||
],
|
|
||||||
"command": {
|
"command": {
|
||||||
"version": {
|
"version": {
|
||||||
"forcePublish": true,
|
"forcePublish": true,
|
||||||
|
@ -44,8 +44,14 @@ import type { CollectionFieldInterfaceFactory } from '../data-source';
|
|||||||
import { OpenModeProvider } from '../modules/popup/OpenModeProvider';
|
import { OpenModeProvider } from '../modules/popup/OpenModeProvider';
|
||||||
import { AppSchemaComponentProvider } from './AppSchemaComponentProvider';
|
import { AppSchemaComponentProvider } from './AppSchemaComponentProvider';
|
||||||
import type { Plugin } from './Plugin';
|
import type { Plugin } from './Plugin';
|
||||||
|
import { getOperators } from './globalOperators';
|
||||||
import type { RequireJS } from './utils/requirejs';
|
import type { RequireJS } from './utils/requirejs';
|
||||||
|
|
||||||
|
type JsonLogic = {
|
||||||
|
addOperation: (name: string, fn?: any) => void;
|
||||||
|
rmOperation: (name: string) => void;
|
||||||
|
};
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
define: RequireJS['define'];
|
define: RequireJS['define'];
|
||||||
@ -100,7 +106,7 @@ export class Application {
|
|||||||
public dataSourceManager: DataSourceManager;
|
public dataSourceManager: DataSourceManager;
|
||||||
public name: string;
|
public name: string;
|
||||||
public globalVars: Record<string, any> = {};
|
public globalVars: Record<string, any> = {};
|
||||||
|
public jsonLogic: JsonLogic;
|
||||||
loading = true;
|
loading = true;
|
||||||
maintained = false;
|
maintained = false;
|
||||||
maintaining = false;
|
maintaining = false;
|
||||||
@ -155,6 +161,7 @@ export class Application {
|
|||||||
this.apiClient.auth.locale = lng;
|
this.apiClient.auth.locale = lng;
|
||||||
});
|
});
|
||||||
this.initListeners();
|
this.initListeners();
|
||||||
|
this.jsonLogic = getOperators();
|
||||||
}
|
}
|
||||||
|
|
||||||
private initListeners() {
|
private initListeners() {
|
||||||
@ -488,4 +495,11 @@ export class Application {
|
|||||||
getGlobalVar(key) {
|
getGlobalVar(key) {
|
||||||
return get(this.globalVars, key);
|
return get(this.globalVars, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerOperators(key, operator) {
|
||||||
|
this.jsonLogic[key] = operator;
|
||||||
|
}
|
||||||
|
getOperator(key) {
|
||||||
|
return this.jsonLogic[key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,11 @@
|
|||||||
|
|
||||||
/* globals define,module */
|
/* globals define,module */
|
||||||
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Using a Universal Module Loader that should be browser, require, and AMD friendly
|
Using a Universal Module Loader that should be browser, require, and AMD friendly
|
||||||
http://ricostacruz.com/cheatsheets/umdjs.html
|
http://ricostacruz.com/cheatsheets/umdjs.html
|
||||||
*/
|
*/
|
||||||
export function getJsonLogic() {
|
export function getOperators() {
|
||||||
'use strict';
|
'use strict';
|
||||||
/* globals console:false */
|
/* globals console:false */
|
||||||
|
|
||||||
@ -359,12 +357,12 @@ export function getJsonLogic() {
|
|||||||
return !!value;
|
return !!value;
|
||||||
};
|
};
|
||||||
|
|
||||||
jsonLogic.get_operator = function (logic) {
|
jsonLogic.getOperator = function (logic) {
|
||||||
return Object.keys(logic)[0];
|
return Object.keys(logic)[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
jsonLogic.get_values = function (logic) {
|
jsonLogic.getValues = function (logic) {
|
||||||
return logic[jsonLogic.get_operator(logic)];
|
return logic[jsonLogic.getOperator(logic)];
|
||||||
};
|
};
|
||||||
|
|
||||||
jsonLogic.apply = function (logic, data) {
|
jsonLogic.apply = function (logic, data) {
|
||||||
@ -379,7 +377,7 @@ export function getJsonLogic() {
|
|||||||
return logic;
|
return logic;
|
||||||
}
|
}
|
||||||
|
|
||||||
var op = jsonLogic.get_operator(logic);
|
var op = jsonLogic.getOperator(logic);
|
||||||
var values = logic[op];
|
var values = logic[op];
|
||||||
var i;
|
var i;
|
||||||
var current;
|
var current;
|
||||||
@ -543,7 +541,7 @@ export function getJsonLogic() {
|
|||||||
var collection = [];
|
var collection = [];
|
||||||
|
|
||||||
if (jsonLogic.is_logic(logic)) {
|
if (jsonLogic.is_logic(logic)) {
|
||||||
var op = jsonLogic.get_operator(logic);
|
var op = jsonLogic.getOperator(logic);
|
||||||
var values = logic[op];
|
var values = logic[op];
|
||||||
|
|
||||||
if (!Array.isArray(values)) {
|
if (!Array.isArray(values)) {
|
||||||
@ -564,11 +562,11 @@ export function getJsonLogic() {
|
|||||||
return arrayUnique(collection);
|
return arrayUnique(collection);
|
||||||
};
|
};
|
||||||
|
|
||||||
jsonLogic.add_operation = function (name, code) {
|
jsonLogic.addOperation = function (name, code) {
|
||||||
operations[name] = code;
|
operations[name] = code;
|
||||||
};
|
};
|
||||||
|
|
||||||
jsonLogic.rm_operation = function (name) {
|
jsonLogic.rmOperation = function (name) {
|
||||||
delete operations[name];
|
delete operations[name];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -593,8 +591,8 @@ export function getJsonLogic() {
|
|||||||
|
|
||||||
if (jsonLogic.is_logic(pattern)) {
|
if (jsonLogic.is_logic(pattern)) {
|
||||||
if (jsonLogic.is_logic(rule)) {
|
if (jsonLogic.is_logic(rule)) {
|
||||||
var pattern_op = jsonLogic.get_operator(pattern);
|
var pattern_op = jsonLogic.getOperator(pattern);
|
||||||
var rule_op = jsonLogic.get_operator(rule);
|
var rule_op = jsonLogic.getOperator(rule);
|
||||||
|
|
||||||
if (pattern_op === '@' || pattern_op === rule_op) {
|
if (pattern_op === '@' || pattern_op === rule_op) {
|
||||||
// echo "\nOperators match, go deeper\n";
|
// echo "\nOperators match, go deeper\n";
|
@ -47,6 +47,7 @@ import { ActionContextProvider } from './context';
|
|||||||
import { useGetAriaLabelOfAction } from './hooks/useGetAriaLabelOfAction';
|
import { useGetAriaLabelOfAction } from './hooks/useGetAriaLabelOfAction';
|
||||||
import { ActionContextProps, ActionProps, ComposedAction } from './types';
|
import { ActionContextProps, ActionProps, ComposedAction } from './types';
|
||||||
import { linkageAction, setInitialActionState } from './utils';
|
import { linkageAction, setInitialActionState } from './utils';
|
||||||
|
import { useApp } from '../../../application';
|
||||||
|
|
||||||
const useA = () => {
|
const useA = () => {
|
||||||
return {
|
return {
|
||||||
@ -95,7 +96,7 @@ export const Action: ComposedAction = withDynamicSchemaProps(
|
|||||||
const { setSubmitted } = useActionContext();
|
const { setSubmitted } = useActionContext();
|
||||||
const { getAriaLabel } = useGetAriaLabelOfAction(title);
|
const { getAriaLabel } = useGetAriaLabelOfAction(title);
|
||||||
const parentRecordData = useCollectionParentRecordData();
|
const parentRecordData = useCollectionParentRecordData();
|
||||||
|
const app = useApp();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (field.stateOfLinkageRules) {
|
if (field.stateOfLinkageRules) {
|
||||||
setInitialActionState(field);
|
setInitialActionState(field);
|
||||||
@ -105,13 +106,16 @@ export const Action: ComposedAction = withDynamicSchemaProps(
|
|||||||
.filter((k) => !k.disabled)
|
.filter((k) => !k.disabled)
|
||||||
.forEach((v) => {
|
.forEach((v) => {
|
||||||
v.actions?.forEach((h) => {
|
v.actions?.forEach((h) => {
|
||||||
linkageAction({
|
linkageAction(
|
||||||
|
{
|
||||||
operator: h.operator,
|
operator: h.operator,
|
||||||
field,
|
field,
|
||||||
condition: v.condition,
|
condition: v.condition,
|
||||||
variables,
|
variables,
|
||||||
localVariables,
|
localVariables,
|
||||||
});
|
},
|
||||||
|
app.jsonLogic,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, [field, linkageRules, localVariables, variables]);
|
}, [field, linkageRules, localVariables, variables]);
|
||||||
|
@ -80,25 +80,28 @@ export const requestSettingsSchema: ISchema = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const linkageAction = async ({
|
export const linkageAction = async (
|
||||||
|
{
|
||||||
operator,
|
operator,
|
||||||
field,
|
field,
|
||||||
condition,
|
condition,
|
||||||
variables,
|
variables,
|
||||||
localVariables,
|
localVariables,
|
||||||
}: {
|
}: {
|
||||||
operator;
|
operator;
|
||||||
field;
|
field;
|
||||||
condition;
|
condition;
|
||||||
variables: VariablesContextType;
|
variables: VariablesContextType;
|
||||||
localVariables: VariableOption[];
|
localVariables: VariableOption[];
|
||||||
}) => {
|
},
|
||||||
|
jsonLogic: any,
|
||||||
|
) => {
|
||||||
const disableResult = field?.stateOfLinkageRules?.disabled || [false];
|
const disableResult = field?.stateOfLinkageRules?.disabled || [false];
|
||||||
const displayResult = field?.stateOfLinkageRules?.display || ['visible'];
|
const displayResult = field?.stateOfLinkageRules?.display || ['visible'];
|
||||||
|
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case ActionType.Visible:
|
case ActionType.Visible:
|
||||||
if (await conditionAnalyses({ ruleGroup: condition, variables, localVariables })) {
|
if (await conditionAnalyses({ ruleGroup: condition, variables, localVariables }, jsonLogic)) {
|
||||||
displayResult.push(operator);
|
displayResult.push(operator);
|
||||||
field.data = field.data || {};
|
field.data = field.data || {};
|
||||||
field.data.hidden = false;
|
field.data.hidden = false;
|
||||||
@ -110,7 +113,7 @@ export const linkageAction = async ({
|
|||||||
field.display = last(displayResult);
|
field.display = last(displayResult);
|
||||||
break;
|
break;
|
||||||
case ActionType.Hidden:
|
case ActionType.Hidden:
|
||||||
if (await conditionAnalyses({ ruleGroup: condition, variables, localVariables })) {
|
if (await conditionAnalyses({ ruleGroup: condition, variables, localVariables }, jsonLogic)) {
|
||||||
field.data = field.data || {};
|
field.data = field.data || {};
|
||||||
field.data.hidden = true;
|
field.data.hidden = true;
|
||||||
} else {
|
} else {
|
||||||
@ -119,7 +122,7 @@ export const linkageAction = async ({
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ActionType.Disabled:
|
case ActionType.Disabled:
|
||||||
if (await conditionAnalyses({ ruleGroup: condition, variables, localVariables })) {
|
if (await conditionAnalyses({ ruleGroup: condition, variables, localVariables }, jsonLogic)) {
|
||||||
disableResult.push(true);
|
disableResult.push(true);
|
||||||
}
|
}
|
||||||
field.stateOfLinkageRules = {
|
field.stateOfLinkageRules = {
|
||||||
@ -130,7 +133,7 @@ export const linkageAction = async ({
|
|||||||
field.componentProps['disabled'] = last(disableResult);
|
field.componentProps['disabled'] = last(disableResult);
|
||||||
break;
|
break;
|
||||||
case ActionType.Active:
|
case ActionType.Active:
|
||||||
if (await conditionAnalyses({ ruleGroup: condition, variables, localVariables })) {
|
if (await conditionAnalyses({ ruleGroup: condition, variables, localVariables }, jsonLogic)) {
|
||||||
disableResult.push(false);
|
disableResult.push(false);
|
||||||
} else {
|
} else {
|
||||||
disableResult.push(!!field.componentProps?.['disabled']);
|
disableResult.push(!!field.componentProps?.['disabled']);
|
||||||
|
@ -16,6 +16,7 @@ import { forEachLinkageRule } from '../../../../schema-settings/LinkageRules/for
|
|||||||
import useLocalVariables from '../../../../variables/hooks/useLocalVariables';
|
import useLocalVariables from '../../../../variables/hooks/useLocalVariables';
|
||||||
import useVariables from '../../../../variables/hooks/useVariables';
|
import useVariables from '../../../../variables/hooks/useVariables';
|
||||||
import { useSubFormValue } from '../../association-field/hooks';
|
import { useSubFormValue } from '../../association-field/hooks';
|
||||||
|
import { useApp } from '../../../../application';
|
||||||
import { isSubMode } from '../../association-field/util';
|
import { isSubMode } from '../../association-field/util';
|
||||||
|
|
||||||
const isSubFormOrSubTableField = (fieldSchema: Schema) => {
|
const isSubFormOrSubTableField = (fieldSchema: Schema) => {
|
||||||
@ -45,6 +46,7 @@ export const useLinkageRulesForSubTableOrSubForm = () => {
|
|||||||
const variables = useVariables();
|
const variables = useVariables();
|
||||||
|
|
||||||
const linkageRules = getLinkageRules(schemaOfSubTableOrSubForm);
|
const linkageRules = getLinkageRules(schemaOfSubTableOrSubForm);
|
||||||
|
const app = useApp();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isSubFormOrSubTableField(fieldSchema)) {
|
if (!isSubFormOrSubTableField(fieldSchema)) {
|
||||||
@ -77,7 +79,8 @@ export const useLinkageRulesForSubTableOrSubForm = () => {
|
|||||||
forEachLinkageRule(linkageRules, (action, rule) => {
|
forEachLinkageRule(linkageRules, (action, rule) => {
|
||||||
if (action.targetFields?.includes(fieldSchema.name)) {
|
if (action.targetFields?.includes(fieldSchema.name)) {
|
||||||
disposes.push(
|
disposes.push(
|
||||||
bindLinkageRulesToFiled({
|
bindLinkageRulesToFiled(
|
||||||
|
{
|
||||||
field,
|
field,
|
||||||
linkageRules,
|
linkageRules,
|
||||||
formValues: formValue,
|
formValues: formValue,
|
||||||
@ -86,7 +89,9 @@ export const useLinkageRulesForSubTableOrSubForm = () => {
|
|||||||
rule,
|
rule,
|
||||||
variables,
|
variables,
|
||||||
variableNameOfLeftCondition: '$iteration',
|
variableNameOfLeftCondition: '$iteration',
|
||||||
}),
|
},
|
||||||
|
app.jsonLogic,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -27,6 +27,7 @@ import { useToken } from '../../../style';
|
|||||||
import { useLocalVariables, useVariables } from '../../../variables';
|
import { useLocalVariables, useVariables } from '../../../variables';
|
||||||
import { useProps } from '../../hooks/useProps';
|
import { useProps } from '../../hooks/useProps';
|
||||||
import { useFormBlockHeight } from './hook';
|
import { useFormBlockHeight } from './hook';
|
||||||
|
import { useApp } from '../../../application';
|
||||||
|
|
||||||
export interface FormProps extends IFormLayoutProps {
|
export interface FormProps extends IFormLayoutProps {
|
||||||
form?: FormilyForm;
|
form?: FormilyForm;
|
||||||
@ -136,6 +137,7 @@ const WithForm = (props: WithFormProps) => {
|
|||||||
const localVariables = useLocalVariables({ currentForm: form });
|
const localVariables = useLocalVariables({ currentForm: form });
|
||||||
const { templateFinished } = useTemplateBlockContext();
|
const { templateFinished } = useTemplateBlockContext();
|
||||||
const { loading } = useDataBlockRequest() || {};
|
const { loading } = useDataBlockRequest() || {};
|
||||||
|
const app = useApp();
|
||||||
const linkageRules: any[] =
|
const linkageRules: any[] =
|
||||||
(getLinkageRules(fieldSchema) || fieldSchema.parent?.['x-linkage-rules'])?.filter((k) => !k.disabled) || [];
|
(getLinkageRules(fieldSchema) || fieldSchema.parent?.['x-linkage-rules'])?.filter((k) => !k.disabled) || [];
|
||||||
|
|
||||||
@ -175,7 +177,8 @@ const WithForm = (props: WithFormProps) => {
|
|||||||
// 之前使用的 `onFieldReact` 有问题,没有办法被取消监听,所以这里用 `onFieldInit` 和 `reaction` 代替
|
// 之前使用的 `onFieldReact` 有问题,没有办法被取消监听,所以这里用 `onFieldInit` 和 `reaction` 代替
|
||||||
onFieldInit(`*(${fields})`, (field: any, form) => {
|
onFieldInit(`*(${fields})`, (field: any, form) => {
|
||||||
disposes.push(
|
disposes.push(
|
||||||
bindLinkageRulesToFiled({
|
bindLinkageRulesToFiled(
|
||||||
|
{
|
||||||
field,
|
field,
|
||||||
linkageRules,
|
linkageRules,
|
||||||
formValues: form.values,
|
formValues: form.values,
|
||||||
@ -183,7 +186,9 @@ const WithForm = (props: WithFormProps) => {
|
|||||||
action,
|
action,
|
||||||
rule,
|
rule,
|
||||||
variables,
|
variables,
|
||||||
}),
|
},
|
||||||
|
app.jsonLogic,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import { VariableOption, VariablesContextType } from '../../../variables/types';
|
|||||||
import { isVariable } from '../../../variables/utils/isVariable';
|
import { isVariable } from '../../../variables/utils/isVariable';
|
||||||
import { transformVariableValue } from '../../../variables/utils/transformVariableValue';
|
import { transformVariableValue } from '../../../variables/utils/transformVariableValue';
|
||||||
import { inferPickerType } from '../../antd/date-picker/util';
|
import { inferPickerType } from '../../antd/date-picker/util';
|
||||||
import { getJsonLogic } from '../../common/utils/logic';
|
|
||||||
type VariablesCtx = {
|
type VariablesCtx = {
|
||||||
/** 当前登录的用户 */
|
/** 当前登录的用户 */
|
||||||
$user?: Record<string, any>;
|
$user?: Record<string, any>;
|
||||||
@ -76,12 +76,13 @@ function getAllKeys(obj) {
|
|||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const conditionAnalyses = async ({
|
export const conditionAnalyses = async (
|
||||||
|
{
|
||||||
ruleGroup,
|
ruleGroup,
|
||||||
variables,
|
variables,
|
||||||
localVariables,
|
localVariables,
|
||||||
variableNameOfLeftCondition,
|
variableNameOfLeftCondition,
|
||||||
}: {
|
}: {
|
||||||
ruleGroup;
|
ruleGroup;
|
||||||
variables: VariablesContextType;
|
variables: VariablesContextType;
|
||||||
localVariables: VariableOption[];
|
localVariables: VariableOption[];
|
||||||
@ -90,17 +91,19 @@ export const conditionAnalyses = async ({
|
|||||||
* @default '$nForm'
|
* @default '$nForm'
|
||||||
*/
|
*/
|
||||||
variableNameOfLeftCondition?: string;
|
variableNameOfLeftCondition?: string;
|
||||||
}) => {
|
},
|
||||||
|
jsonLogic: any,
|
||||||
|
) => {
|
||||||
const type = Object.keys(ruleGroup)[0] || '$and';
|
const type = Object.keys(ruleGroup)[0] || '$and';
|
||||||
const conditions = ruleGroup[type];
|
const conditions = ruleGroup[type];
|
||||||
|
|
||||||
let results = conditions.map(async (condition) => {
|
let results = conditions.map(async (condition) => {
|
||||||
if ('$and' in condition || '$or' in condition) {
|
if ('$and' in condition || '$or' in condition) {
|
||||||
return await conditionAnalyses({ ruleGroup: condition, variables, localVariables });
|
return await conditionAnalyses({ ruleGroup: condition, variables, localVariables }, jsonLogic);
|
||||||
}
|
}
|
||||||
|
|
||||||
const jsonlogic = getInnermostKeyAndValue(condition);
|
const logicCalculation = getInnermostKeyAndValue(condition);
|
||||||
const operator = jsonlogic?.key;
|
const operator = logicCalculation?.key;
|
||||||
|
|
||||||
if (!operator) {
|
if (!operator) {
|
||||||
return true;
|
return true;
|
||||||
@ -113,12 +116,11 @@ export const conditionAnalyses = async ({
|
|||||||
})
|
})
|
||||||
.then(({ value }) => value);
|
.then(({ value }) => value);
|
||||||
|
|
||||||
const parsingResult = isVariable(jsonlogic?.value)
|
const parsingResult = isVariable(logicCalculation?.value)
|
||||||
? [variables.parseVariable(jsonlogic?.value, localVariables).then(({ value }) => value), targetValue]
|
? [variables.parseVariable(logicCalculation?.value, localVariables).then(({ value }) => value), targetValue]
|
||||||
: [jsonlogic?.value, targetValue];
|
: [logicCalculation?.value, targetValue];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const jsonLogic = getJsonLogic();
|
|
||||||
const [value, targetValue] = await Promise.all(parsingResult);
|
const [value, targetValue] = await Promise.all(parsingResult);
|
||||||
const targetCollectionField = await variables.getCollectionField(targetVariableName, localVariables);
|
const targetCollectionField = await variables.getCollectionField(targetVariableName, localVariables);
|
||||||
let currentInputValue = transformVariableValue(targetValue, { targetCollectionField });
|
let currentInputValue = transformVariableValue(targetValue, { targetCollectionField });
|
||||||
|
@ -22,6 +22,7 @@ import { linkageAction } from '../../schema-component/antd/action/utils';
|
|||||||
import { usePopupUtils } from '../../schema-component/antd/page/pagePopupUtils';
|
import { usePopupUtils } from '../../schema-component/antd/page/pagePopupUtils';
|
||||||
import { parseVariables } from '../../schema-component/common/utils/uitls';
|
import { parseVariables } from '../../schema-component/common/utils/uitls';
|
||||||
import { useLocalVariables, useVariables } from '../../variables';
|
import { useLocalVariables, useVariables } from '../../variables';
|
||||||
|
import { useApp } from '../../application';
|
||||||
|
|
||||||
export function useAclCheck(actionPath) {
|
export function useAclCheck(actionPath) {
|
||||||
const aclCheck = useAclCheckFn();
|
const aclCheck = useAclCheckFn();
|
||||||
@ -73,6 +74,7 @@ const InternalCreateRecordAction = (props: any, ref) => {
|
|||||||
const { openPopup } = usePopupUtils();
|
const { openPopup } = usePopupUtils();
|
||||||
const treeRecordData = useTreeParentRecord();
|
const treeRecordData = useTreeParentRecord();
|
||||||
const cm = useCollectionManager();
|
const cm = useCollectionManager();
|
||||||
|
const app = useApp();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
field.stateOfLinkageRules = {};
|
field.stateOfLinkageRules = {};
|
||||||
@ -80,13 +82,16 @@ const InternalCreateRecordAction = (props: any, ref) => {
|
|||||||
.filter((k) => !k.disabled)
|
.filter((k) => !k.disabled)
|
||||||
.forEach((v) => {
|
.forEach((v) => {
|
||||||
v.actions?.forEach((h) => {
|
v.actions?.forEach((h) => {
|
||||||
linkageAction({
|
linkageAction(
|
||||||
|
{
|
||||||
operator: h.operator,
|
operator: h.operator,
|
||||||
field,
|
field,
|
||||||
condition: v.condition,
|
condition: v.condition,
|
||||||
variables,
|
variables,
|
||||||
localVariables,
|
localVariables,
|
||||||
});
|
},
|
||||||
|
app.jsonLogic,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, [field, linkageRules, localVariables, variables]);
|
}, [field, linkageRules, localVariables, variables]);
|
||||||
@ -143,7 +148,6 @@ export const CreateAction = observer(
|
|||||||
const form = useForm();
|
const form = useForm();
|
||||||
const variables = useVariables();
|
const variables = useVariables();
|
||||||
const aclCheck = useAclCheckFn();
|
const aclCheck = useAclCheckFn();
|
||||||
|
|
||||||
const enableChildren = fieldSchema['x-enable-children'] || [];
|
const enableChildren = fieldSchema['x-enable-children'] || [];
|
||||||
const allowAddToCurrent = fieldSchema?.['x-allow-add-to-current'];
|
const allowAddToCurrent = fieldSchema?.['x-allow-add-to-current'];
|
||||||
const linkageFromForm = fieldSchema?.['x-component-props']?.['linkageFromForm'];
|
const linkageFromForm = fieldSchema?.['x-component-props']?.['linkageFromForm'];
|
||||||
@ -176,6 +180,7 @@ export const CreateAction = observer(
|
|||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
const { designable } = useDesignable();
|
const { designable } = useDesignable();
|
||||||
const icon = props.icon || null;
|
const icon = props.icon || null;
|
||||||
|
const app = useApp();
|
||||||
const menuItems = useMemo<MenuProps['items']>(() => {
|
const menuItems = useMemo<MenuProps['items']>(() => {
|
||||||
return inheritsCollections.map((option) => ({
|
return inheritsCollections.map((option) => ({
|
||||||
key: option.name,
|
key: option.name,
|
||||||
@ -196,13 +201,16 @@ export const CreateAction = observer(
|
|||||||
.filter((k) => !k.disabled)
|
.filter((k) => !k.disabled)
|
||||||
.forEach((v) => {
|
.forEach((v) => {
|
||||||
v.actions?.forEach((h) => {
|
v.actions?.forEach((h) => {
|
||||||
linkageAction({
|
linkageAction(
|
||||||
|
{
|
||||||
operator: h.operator,
|
operator: h.operator,
|
||||||
field,
|
field,
|
||||||
condition: v.condition,
|
condition: v.condition,
|
||||||
variables,
|
variables,
|
||||||
localVariables,
|
localVariables,
|
||||||
});
|
},
|
||||||
|
app.jsonLogic,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, [field, linkageRules, localVariables, variables]);
|
}, [field, linkageRules, localVariables, variables]);
|
||||||
|
@ -39,7 +39,8 @@ interface Props {
|
|||||||
variableNameOfLeftCondition?: string;
|
variableNameOfLeftCondition?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bindLinkageRulesToFiled({
|
export function bindLinkageRulesToFiled(
|
||||||
|
{
|
||||||
field,
|
field,
|
||||||
linkageRules,
|
linkageRules,
|
||||||
formValues,
|
formValues,
|
||||||
@ -48,7 +49,7 @@ export function bindLinkageRulesToFiled({
|
|||||||
rule,
|
rule,
|
||||||
variables,
|
variables,
|
||||||
variableNameOfLeftCondition,
|
variableNameOfLeftCondition,
|
||||||
}: {
|
}: {
|
||||||
field: any;
|
field: any;
|
||||||
linkageRules: any[];
|
linkageRules: any[];
|
||||||
formValues: any;
|
formValues: any;
|
||||||
@ -61,7 +62,9 @@ export function bindLinkageRulesToFiled({
|
|||||||
* @default '$nForm'
|
* @default '$nForm'
|
||||||
*/
|
*/
|
||||||
variableNameOfLeftCondition?: string;
|
variableNameOfLeftCondition?: string;
|
||||||
}) {
|
},
|
||||||
|
jsonLogic: any,
|
||||||
|
) {
|
||||||
field['initStateOfLinkageRules'] = {
|
field['initStateOfLinkageRules'] = {
|
||||||
display: field.initStateOfLinkageRules?.display || getTempFieldState(true, field.display),
|
display: field.initStateOfLinkageRules?.display || getTempFieldState(true, field.display),
|
||||||
required: field.initStateOfLinkageRules?.required || getTempFieldState(true, field.required || false),
|
required: field.initStateOfLinkageRules?.required || getTempFieldState(true, field.required || false),
|
||||||
@ -89,7 +92,7 @@ export function bindLinkageRulesToFiled({
|
|||||||
.join(',');
|
.join(',');
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
getSubscriber({ action, field, rule, variables, localVariables, variableNameOfLeftCondition }),
|
getSubscriber({ action, field, rule, variables, localVariables, variableNameOfLeftCondition }, jsonLogic),
|
||||||
{ fireImmediately: true, equals: _.isEqual },
|
{ fireImmediately: true, equals: _.isEqual },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -176,14 +179,15 @@ function getVariableValue(variableString: string, localVariables: VariableOption
|
|||||||
return getValuesByPath(ctx, getPath(variableString));
|
return getValuesByPath(ctx, getPath(variableString));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSubscriber({
|
function getSubscriber(
|
||||||
|
{
|
||||||
action,
|
action,
|
||||||
field,
|
field,
|
||||||
rule,
|
rule,
|
||||||
variables,
|
variables,
|
||||||
localVariables,
|
localVariables,
|
||||||
variableNameOfLeftCondition,
|
variableNameOfLeftCondition,
|
||||||
}: {
|
}: {
|
||||||
action: any;
|
action: any;
|
||||||
field: any;
|
field: any;
|
||||||
rule: any;
|
rule: any;
|
||||||
@ -194,10 +198,13 @@ function getSubscriber({
|
|||||||
* @default '$nForm'
|
* @default '$nForm'
|
||||||
*/
|
*/
|
||||||
variableNameOfLeftCondition?: string;
|
variableNameOfLeftCondition?: string;
|
||||||
}): (value: string, oldValue: string) => void {
|
},
|
||||||
|
jsonLogic,
|
||||||
|
): (value: string, oldValue: string) => void {
|
||||||
return () => {
|
return () => {
|
||||||
// 当条件改变触发 reaction 时,会同步收集字段状态,并保存到 field.stateOfLinkageRules 中
|
// 当条件改变触发 reaction 时,会同步收集字段状态,并保存到 field.stateOfLinkageRules 中
|
||||||
collectFieldStateOfLinkageRules({
|
collectFieldStateOfLinkageRules(
|
||||||
|
{
|
||||||
operator: action.operator,
|
operator: action.operator,
|
||||||
value: action.value,
|
value: action.value,
|
||||||
field,
|
field,
|
||||||
@ -205,7 +212,9 @@ function getSubscriber({
|
|||||||
variables,
|
variables,
|
||||||
localVariables,
|
localVariables,
|
||||||
variableNameOfLeftCondition,
|
variableNameOfLeftCondition,
|
||||||
});
|
},
|
||||||
|
jsonLogic,
|
||||||
|
);
|
||||||
|
|
||||||
// 当条件改变时,有可能会触发多个 reaction,所以这里需要延迟一下,确保所有的 reaction 都执行完毕后,
|
// 当条件改变时,有可能会触发多个 reaction,所以这里需要延迟一下,确保所有的 reaction 都执行完毕后,
|
||||||
// 再从 field.stateOfLinkageRules 中取值,因为此时 field.stateOfLinkageRules 中的值才是全的。
|
// 再从 field.stateOfLinkageRules 中取值,因为此时 field.stateOfLinkageRules 中的值才是全的。
|
||||||
@ -286,15 +295,10 @@ function getFieldNameByOperator(operator: ActionType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const collectFieldStateOfLinkageRules = ({
|
export const collectFieldStateOfLinkageRules = (
|
||||||
operator,
|
{ operator, value, field, condition, variables, localVariables, variableNameOfLeftCondition }: Props,
|
||||||
value,
|
jsonLogic: any,
|
||||||
field,
|
) => {
|
||||||
condition,
|
|
||||||
variables,
|
|
||||||
localVariables,
|
|
||||||
variableNameOfLeftCondition,
|
|
||||||
}: Props) => {
|
|
||||||
const requiredResult = field?.stateOfLinkageRules?.required || [field?.initStateOfLinkageRules?.required];
|
const requiredResult = field?.stateOfLinkageRules?.required || [field?.initStateOfLinkageRules?.required];
|
||||||
const displayResult = field?.stateOfLinkageRules?.display || [field?.initStateOfLinkageRules?.display];
|
const displayResult = field?.stateOfLinkageRules?.display || [field?.initStateOfLinkageRules?.display];
|
||||||
const patternResult = field?.stateOfLinkageRules?.pattern || [field?.initStateOfLinkageRules?.pattern];
|
const patternResult = field?.stateOfLinkageRules?.pattern || [field?.initStateOfLinkageRules?.pattern];
|
||||||
@ -304,14 +308,14 @@ export const collectFieldStateOfLinkageRules = ({
|
|||||||
|
|
||||||
switch (operator) {
|
switch (operator) {
|
||||||
case ActionType.Required:
|
case ActionType.Required:
|
||||||
requiredResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult), true));
|
requiredResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult, jsonLogic), true));
|
||||||
field.stateOfLinkageRules = {
|
field.stateOfLinkageRules = {
|
||||||
...field.stateOfLinkageRules,
|
...field.stateOfLinkageRules,
|
||||||
required: requiredResult,
|
required: requiredResult,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case ActionType.InRequired:
|
case ActionType.InRequired:
|
||||||
requiredResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult), false));
|
requiredResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult, jsonLogic), false));
|
||||||
field.stateOfLinkageRules = {
|
field.stateOfLinkageRules = {
|
||||||
...field.stateOfLinkageRules,
|
...field.stateOfLinkageRules,
|
||||||
required: requiredResult,
|
required: requiredResult,
|
||||||
@ -320,7 +324,7 @@ export const collectFieldStateOfLinkageRules = ({
|
|||||||
case ActionType.Visible:
|
case ActionType.Visible:
|
||||||
case ActionType.None:
|
case ActionType.None:
|
||||||
case ActionType.Hidden:
|
case ActionType.Hidden:
|
||||||
displayResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult), operator));
|
displayResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult, jsonLogic), operator));
|
||||||
field.stateOfLinkageRules = {
|
field.stateOfLinkageRules = {
|
||||||
...field.stateOfLinkageRules,
|
...field.stateOfLinkageRules,
|
||||||
display: displayResult,
|
display: displayResult,
|
||||||
@ -329,7 +333,7 @@ export const collectFieldStateOfLinkageRules = ({
|
|||||||
case ActionType.Editable:
|
case ActionType.Editable:
|
||||||
case ActionType.ReadOnly:
|
case ActionType.ReadOnly:
|
||||||
case ActionType.ReadPretty:
|
case ActionType.ReadPretty:
|
||||||
patternResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult), operator));
|
patternResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult, jsonLogic), operator));
|
||||||
field.stateOfLinkageRules = {
|
field.stateOfLinkageRules = {
|
||||||
...field.stateOfLinkageRules,
|
...field.stateOfLinkageRules,
|
||||||
pattern: patternResult,
|
pattern: patternResult,
|
||||||
@ -364,7 +368,7 @@ export const collectFieldStateOfLinkageRules = ({
|
|||||||
if (isConditionEmpty(condition)) {
|
if (isConditionEmpty(condition)) {
|
||||||
valueResult.push(getTempFieldState(true, getValue()));
|
valueResult.push(getTempFieldState(true, getValue()));
|
||||||
} else {
|
} else {
|
||||||
valueResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult), getValue()));
|
valueResult.push(getTempFieldState(conditionAnalyses(paramsToGetConditionResult, jsonLogic), getValue()));
|
||||||
}
|
}
|
||||||
field.stateOfLinkageRules = {
|
field.stateOfLinkageRules = {
|
||||||
...field.stateOfLinkageRules,
|
...field.stateOfLinkageRules,
|
||||||
|
@ -25,13 +25,13 @@ const getActionValue = (operator, value) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSatisfiedActions = async ({ rules, variables, localVariables }) => {
|
const getSatisfiedActions = async ({ rules, variables, localVariables }, jsonLogic) => {
|
||||||
const satisfiedRules = (
|
const satisfiedRules = (
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
rules
|
rules
|
||||||
.filter((k) => !k.disabled)
|
.filter((k) => !k.disabled)
|
||||||
.map(async (rule) => {
|
.map(async (rule) => {
|
||||||
if (await conditionAnalyses({ ruleGroup: rule.condition, variables, localVariables })) {
|
if (await conditionAnalyses({ ruleGroup: rule.condition, variables, localVariables }, jsonLogic)) {
|
||||||
return rule;
|
return rule;
|
||||||
} else return null;
|
} else return null;
|
||||||
}),
|
}),
|
||||||
@ -40,15 +40,15 @@ const getSatisfiedActions = async ({ rules, variables, localVariables }) => {
|
|||||||
return satisfiedRules.map((rule) => rule.actions).flat();
|
return satisfiedRules.map((rule) => rule.actions).flat();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSatisfiedValues = async ({ rules, variables, localVariables }) => {
|
const getSatisfiedValues = async ({ rules, variables, localVariables }, jsonLogic) => {
|
||||||
return (await getSatisfiedActions({ rules, variables, localVariables })).map((action) => ({
|
return (await getSatisfiedActions({ rules, variables, localVariables }, jsonLogic)).map((action) => ({
|
||||||
...action,
|
...action,
|
||||||
value: getActionValue(action.operator, action.value),
|
value: getActionValue(action.operator, action.value),
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSatisfiedValueMap = async ({ rules, variables, localVariables }) => {
|
export const getSatisfiedValueMap = async ({ rules, variables, localVariables }, jsonLogic) => {
|
||||||
const values = await getSatisfiedValues({ rules, variables, localVariables });
|
const values = await getSatisfiedValues({ rules, variables, localVariables }, jsonLogic);
|
||||||
const valueMap = values.reduce((a, v) => ({ ...a, [v.operator]: v.value }), {});
|
const valueMap = values.reduce((a, v) => ({ ...a, [v.operator]: v.value }), {});
|
||||||
return valueMap;
|
return valueMap;
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,7 @@ import React, { useCallback, useEffect, useState } from 'react';
|
|||||||
import { useLocalVariables, useVariables } from '../../variables';
|
import { useLocalVariables, useVariables } from '../../variables';
|
||||||
import { getSatisfiedValueMap } from './compute-rules';
|
import { getSatisfiedValueMap } from './compute-rules';
|
||||||
import { LinkageRuleCategory, LinkageRuleDataKeyMap } from './type';
|
import { LinkageRuleCategory, LinkageRuleDataKeyMap } from './type';
|
||||||
|
import { useApp } from '../../application';
|
||||||
export function useSatisfiedActionValues({
|
export function useSatisfiedActionValues({
|
||||||
formValues,
|
formValues,
|
||||||
category = 'default',
|
category = 'default',
|
||||||
@ -35,10 +35,11 @@ export function useSatisfiedActionValues({
|
|||||||
const localVariables = useLocalVariables({ currentForm: { values: formValues } as any });
|
const localVariables = useLocalVariables({ currentForm: { values: formValues } as any });
|
||||||
const localSchema = schema ?? fieldSchema;
|
const localSchema = schema ?? fieldSchema;
|
||||||
const styleRules = rules ?? localSchema[LinkageRuleDataKeyMap[category]];
|
const styleRules = rules ?? localSchema[LinkageRuleDataKeyMap[category]];
|
||||||
|
const app = useApp();
|
||||||
|
|
||||||
const compute = useCallback(() => {
|
const compute = useCallback(() => {
|
||||||
if (styleRules && formValues) {
|
if (styleRules && formValues) {
|
||||||
getSatisfiedValueMap({ rules: styleRules, variables, localVariables })
|
getSatisfiedValueMap({ rules: styleRules, variables, localVariables }, app.jsonLogic)
|
||||||
.then((valueMap) => {
|
.then((valueMap) => {
|
||||||
if (!isEmpty(valueMap)) {
|
if (!isEmpty(valueMap)) {
|
||||||
setValueMap(valueMap);
|
setValueMap(valueMap);
|
||||||
|
@ -121,9 +121,11 @@ const RuleTypes = {
|
|||||||
number: t('Number', { ns: NAMESPACE }),
|
number: t('Number', { ns: NAMESPACE }),
|
||||||
lowercase: t('Lowercase letters', { ns: NAMESPACE }),
|
lowercase: t('Lowercase letters', { ns: NAMESPACE }),
|
||||||
uppercase: t('Uppercase letters', { ns: NAMESPACE }),
|
uppercase: t('Uppercase letters', { ns: NAMESPACE }),
|
||||||
symbol: t('Symbols', { ns: NAMESPACE })
|
symbol: t('Symbols', { ns: NAMESPACE }),
|
||||||
};
|
};
|
||||||
return <code>{value?.map(charset => charsetLabels[charset]).join(', ') || t('Number', { ns: NAMESPACE })}</code>;
|
return (
|
||||||
|
<code>{value?.map((charset) => charsetLabels[charset]).join(', ') || t('Number', { ns: NAMESPACE })}</code>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fieldset: {
|
fieldset: {
|
||||||
@ -154,14 +156,14 @@ const RuleTypes = {
|
|||||||
{ value: 'number', label: `{{t("Number", { ns: "${NAMESPACE}" })}}` },
|
{ value: 'number', label: `{{t("Number", { ns: "${NAMESPACE}" })}}` },
|
||||||
{ value: 'lowercase', label: `{{t("Lowercase letters", { ns: "${NAMESPACE}" })}}` },
|
{ value: 'lowercase', label: `{{t("Lowercase letters", { ns: "${NAMESPACE}" })}}` },
|
||||||
{ value: 'uppercase', label: `{{t("Uppercase letters", { ns: "${NAMESPACE}" })}}` },
|
{ value: 'uppercase', label: `{{t("Uppercase letters", { ns: "${NAMESPACE}" })}}` },
|
||||||
{ value: 'symbol', label: `{{t("Symbols", { ns: "${NAMESPACE}" })}}` }
|
{ value: 'symbol', label: `{{t("Symbols", { ns: "${NAMESPACE}" })}}` },
|
||||||
],
|
],
|
||||||
required: true,
|
required: true,
|
||||||
default: ['number'],
|
default: ['number'],
|
||||||
'x-validator': {
|
'x-validator': {
|
||||||
minItems: 1,
|
minItems: 1,
|
||||||
message: `{{t("At least one character set should be selected", { ns: "${NAMESPACE}" })}}`
|
message: `{{t("At least one character set should be selected", { ns: "${NAMESPACE}" })}}`,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaults: {
|
defaults: {
|
||||||
|
@ -301,7 +301,7 @@ const CHAR_SETS = {
|
|||||||
lowercase: 'abcdefghijklmnopqrstuvwxyz',
|
lowercase: 'abcdefghijklmnopqrstuvwxyz',
|
||||||
uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||||
// 符号只保留常用且安全的符号,有需要的可以自己加比如[]{}|;:,.<>放在链接或者文件名里容易出问题的字符
|
// 符号只保留常用且安全的符号,有需要的可以自己加比如[]{}|;:,.<>放在链接或者文件名里容易出问题的字符
|
||||||
symbol: '!@#$%^&*_-+'
|
symbol: '!@#$%^&*_-+',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
interface RandomCharOptions {
|
interface RandomCharOptions {
|
||||||
@ -317,21 +317,16 @@ sequencePatterns.register('randomChar', {
|
|||||||
if (!options?.charsets || options.charsets.length === 0) {
|
if (!options?.charsets || options.charsets.length === 0) {
|
||||||
return 'At least one character set should be selected';
|
return 'At least one character set should be selected';
|
||||||
}
|
}
|
||||||
if (options.charsets.some(charset => !CHAR_SETS[charset])) {
|
if (options.charsets.some((charset) => !CHAR_SETS[charset])) {
|
||||||
return 'Invalid charset selected';
|
return 'Invalid charset selected';
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
generate(instance: any, options: RandomCharOptions) {
|
generate(instance: any, options: RandomCharOptions) {
|
||||||
const {
|
const { length = 6, charsets = ['number'] } = options;
|
||||||
length = 6,
|
|
||||||
charsets = ['number']
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
const chars = [...new Set(
|
const chars = [...new Set(charsets.reduce((acc, charset) => acc + CHAR_SETS[charset], ''))];
|
||||||
charsets.reduce((acc, charset) => acc + CHAR_SETS[charset], '')
|
|
||||||
)];
|
|
||||||
|
|
||||||
const getRandomChar = () => {
|
const getRandomChar = () => {
|
||||||
const randomIndex = Math.floor(Math.random() * chars.length);
|
const randomIndex = Math.floor(Math.random() * chars.length);
|
||||||
@ -352,20 +347,27 @@ sequencePatterns.register('randomChar', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getMatcher(options: RandomCharOptions) {
|
getMatcher(options: RandomCharOptions) {
|
||||||
const pattern = [...new Set(
|
const pattern = [
|
||||||
|
...new Set(
|
||||||
(options.charsets || ['number']).reduce((acc, charset) => {
|
(options.charsets || ['number']).reduce((acc, charset) => {
|
||||||
switch (charset) {
|
switch (charset) {
|
||||||
case 'number': return acc + '0-9';
|
case 'number':
|
||||||
case 'lowercase': return acc + 'a-z';
|
return acc + '0-9';
|
||||||
case 'uppercase': return acc + 'A-Z';
|
case 'lowercase':
|
||||||
case 'symbol': return acc + CHAR_SETS.symbol.replace('-', '').replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '-';
|
return acc + 'a-z';
|
||||||
default: return acc;
|
case 'uppercase':
|
||||||
|
return acc + 'A-Z';
|
||||||
|
case 'symbol':
|
||||||
|
return acc + CHAR_SETS.symbol.replace('-', '').replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '-';
|
||||||
|
default:
|
||||||
|
return acc;
|
||||||
}
|
}
|
||||||
}, '')
|
}, ''),
|
||||||
)].join('');
|
),
|
||||||
|
].join('');
|
||||||
|
|
||||||
return `[${pattern}]{${options.length || 6}}`;
|
return `[${pattern}]{${options.length || 6}}`;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
interface PatternConfig {
|
interface PatternConfig {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user