refactor(plugin-field-sequence): change rule configuration to standard modal

This commit is contained in:
mytharcher 2025-04-16 18:56:45 +08:00
parent 5eda5ba21d
commit ee2da3fbc0
2 changed files with 113 additions and 64 deletions

View File

@ -7,24 +7,23 @@
* For more information, please refer to: https://www.nocobase.com/agreement. * For more information, please refer to: https://www.nocobase.com/agreement.
*/ */
import { ArrayTable, FormButtonGroup, FormDrawer, FormLayout, Submit } from '@formily/antd-v5'; import { ArrayTable } from '@formily/antd-v5';
import { onFieldValueChange } from '@formily/core'; import { createForm, onFieldValueChange } from '@formily/core';
import { ISchema, SchemaOptionsContext, useForm, useFormEffects } from '@formily/react'; import { SchemaOptionsContext, useForm, useFormEffects } from '@formily/react';
import { import {
CollectionFieldInterface, CollectionFieldInterface,
Cron, Cron,
SchemaComponent, SchemaComponent,
SchemaComponentOptions,
css, css,
interfacesProperties, interfacesProperties,
useActionContext,
useCompile, useCompile,
useToken, useToken,
} from '@nocobase/client'; } from '@nocobase/client';
import { error } from '@nocobase/utils/client'; import React, { createContext, useContext, useMemo } from 'react';
import { Button, Select } from 'antd';
import React, { useContext } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { NAMESPACE, lang } from './locale'; import { NAMESPACE, lang } from './locale';
import { Select } from 'antd';
function RuleTypeSelect(props) { function RuleTypeSelect(props) {
const compile = useCompile(); const compile = useCompile();
@ -285,63 +284,109 @@ const RuleTypes = {
}, },
}; };
export function RuleConfigForm() { const ParentFormContext = createContext({} as any);
const { t } = useTranslation(); ParentFormContext.displayName = 'ParentFormContext';
const compile = useCompile();
const schemaOptions = useContext(SchemaOptionsContext); function useRuleUpdateAction() {
const { values, setValuesIn } = useForm(); const parentForm = useContext(ParentFormContext);
const index = ArrayTable.useIndex(); const index = ArrayTable.useIndex();
const { type, options } = values.patterns[index]; const { type, options } = parentForm.values.patterns[index];
const form = useForm();
const { setVisible } = useActionContext();
return {
run() {
parentForm.setValuesIn(`patterns.${index}`, { type, options: { ...form.values } });
setVisible(false);
},
};
}
function useRuleCancelAction() {
const form = useForm();
const { setVisible } = useActionContext();
return {
run() {
form.reset();
setVisible(false);
},
};
}
export function RuleConfigForm() {
const parentForm = useForm();
const index = ArrayTable.useIndex();
const { type, options } = parentForm.values.patterns[index];
const ruleType = RuleTypes[type]; const ruleType = RuleTypes[type];
const { token } = useToken(); const form = useMemo(
() =>
createForm({
initialValues: options,
values: options,
}),
[options],
);
return ruleType?.fieldset ? ( return ruleType?.fieldset ? (
<Button <ParentFormContext.Provider value={parentForm}>
type="link"
onClick={() => {
// fix https://nocobase.height.app/T-2868
FormDrawer({ title: compile(ruleType.title), zIndex: token.zIndexPopupBase + 1000 }, () => {
return (
<FormLayout layout="vertical">
<SchemaComponentOptions scope={schemaOptions.scope} components={schemaOptions.components}>
<SchemaComponent <SchemaComponent
scope={{
useRuleCancelAction,
useRuleUpdateAction,
}}
schema={{ schema={{
type: 'object', name: 'action',
'x-component': 'fieldset', type: 'void',
properties: ruleType.fieldset, 'x-component': 'Action.Link',
'x-component-props': {
openMode: 'modal',
openSize: 'small',
},
title: `{{t("Configure", { ns: "${NAMESPACE}" })}}`,
properties: {
container: {
type: 'void',
title: `{{t("Configure", { ns: "${NAMESPACE}" })}}`,
'x-decorator': 'FormV2',
'x-decorator-props': {
form,
},
'x-component': 'Action.Container',
'x-component-props': {
delay: 0,
},
properties: {
...ruleType.fieldset,
actions: {
type: 'void',
'x-component': 'ActionBar',
properties: {
cancel: {
type: 'void',
'x-component': 'Action',
title: `{{t("Cancel", { ns: "${NAMESPACE}" })}}`,
'x-component-props': {
useAction: '{{useRuleCancelAction}}',
},
},
submit: {
type: 'void',
'x-component': 'Action',
title: `{{t("Submit", { ns: "${NAMESPACE}" })}}`,
'x-component-props': {
type: 'primary',
useAction: '{{useRuleUpdateAction}}',
},
},
},
},
},
},
},
}} }}
/> />
</SchemaComponentOptions> </ParentFormContext.Provider>
<FormDrawer.Footer>
<FormButtonGroup
className={css`
justify-content: flex-end;
`}
>
<Submit
onSubmit={(values) => {
return values;
}}
>
{t('Submit')}
</Submit>
</FormButtonGroup>
</FormDrawer.Footer>
</FormLayout>
);
})
.open({
initialValues: options,
})
.then((values) => {
setValuesIn(`patterns.${index}`, { type, options: { ...values } });
})
.catch((err) => {
error(err);
});
}}
>
{t('Configure')}
</Button>
) : null; ) : null;
} }
@ -464,15 +509,17 @@ export class SequenceFieldInterface extends CollectionFieldInterface {
}, },
inputable: { inputable: {
type: 'boolean', type: 'boolean',
title: `{{t("Inputable", { ns: "${NAMESPACE}" })}}`,
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
'x-component': 'Checkbox', 'x-component': 'Checkbox',
'x-content': `{{t("Inputable", { ns: "${NAMESPACE}" })}}`,
description: `{{t("Allow users to input values manually.", { ns: "${NAMESPACE}" })}}`,
}, },
match: { match: {
type: 'boolean', type: 'boolean',
title: `{{t("Match rules", { ns: "${NAMESPACE}" })}}`,
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
'x-component': 'Checkbox', 'x-component': 'Checkbox',
'x-content': `{{t("Match rules", { ns: "${NAMESPACE}" })}}`,
description: `{{t("Input value must match the rules set above. Otherwise an invalid error will show when submit.", { ns: "${NAMESPACE}" })}}`,
'x-reactions': { 'x-reactions': {
dependencies: ['inputable'], dependencies: ['inputable'],
fulfill: { fulfill: {

View File

@ -4,6 +4,8 @@
"Sequence rules": "编号规则", "Sequence rules": "编号规则",
"Add rule": "添加规则", "Add rule": "添加规则",
"Inputable": "可输入", "Inputable": "可输入",
"Allow users to input values manually.": "允许用户手动输入值。",
"Input value must match the rules set above.": "输入的值必须与上方设置的规则匹配。",
"Match rules": "输入必须匹配规则", "Match rules": "输入必须匹配规则",
"Type": "类型", "Type": "类型",
"Autoincrement": "自增数字", "Autoincrement": "自增数字",
@ -29,7 +31,7 @@
"Length": "长度", "Length": "长度",
"Will generate random characters with specified length.": "将生成指定长度的随机字符。", "Will generate random characters with specified length.": "将生成指定长度的随机字符。",
"Character sets": "字符集", "Character sets": "字符集",
"Select character sets to generate random characters.": "选择用于生成随机字符的字符集。", "Select character sets to generate random characters. Otherwise an invalid error will show when submit.": "选择用于生成随机字符的字符集。否则提交时将提示错误。",
"Number": "数字", "Number": "数字",
"Lowercase letters": "小写字母", "Lowercase letters": "小写字母",
"Uppercase letters": "大写字母", "Uppercase letters": "大写字母",