Fix(plugin workflow) (#346)
* fix(plugin-workflow): try fix i18n in tooltips * fix(plugin-workflow): fix i18n contents and change model event to collection event
This commit is contained in:
parent
c1128bf150
commit
b7ea6b0a5e
@ -280,5 +280,8 @@ export default {
|
|||||||
"Add card": "Add card",
|
"Add card": "Add card",
|
||||||
"edit title": "Edit Title",
|
"edit title": "Edit Title",
|
||||||
"Turn the page": "Turn the page",
|
"Turn the page": "Turn the page",
|
||||||
"Others": "Others"
|
"Others": "Others",
|
||||||
|
|
||||||
|
// workflows
|
||||||
|
'Execution History': 'History',
|
||||||
}
|
}
|
||||||
|
@ -318,6 +318,7 @@ export default {
|
|||||||
|
|
||||||
'Skip required validation': '跳过必填校验',
|
'Skip required validation': '跳过必填校验',
|
||||||
'Form values': '表单值',
|
'Form values': '表单值',
|
||||||
|
'Fields values': '字段值',
|
||||||
'When submitting the following fields, the saved values are': '提交以下字段时,保存的值为',
|
'When submitting the following fields, the saved values are': '提交以下字段时,保存的值为',
|
||||||
'After successful submission': '提交成功后',
|
'After successful submission': '提交成功后',
|
||||||
'Then': '然后',
|
'Then': '然后',
|
||||||
@ -407,25 +408,24 @@ export default {
|
|||||||
|
|
||||||
// plugins/workflow
|
// plugins/workflow
|
||||||
'Workflow': '工作流',
|
'Workflow': '工作流',
|
||||||
'Configure workflow': '流程配置',
|
'Execution History': '执行历史',
|
||||||
'Executions': '执行历史',
|
|
||||||
'Trigger type': '触发方式',
|
'Trigger type': '触发方式',
|
||||||
'Description': '描述',
|
'Description': '描述',
|
||||||
'Status': '状态',
|
'Status': '状态',
|
||||||
'Enabled': '启用',
|
'Enabled': '启用',
|
||||||
'Disabled': '禁用',
|
'Disabled': '禁用',
|
||||||
'Trigger configuration': '触发器配置',
|
|
||||||
'Load failed': '加载失败',
|
'Load failed': '加载失败',
|
||||||
|
|
||||||
'Model event': '数据表事件',
|
'Trigger': '触发器',
|
||||||
|
'Collection event': '数据表事件',
|
||||||
'Trigger on': '触发时机',
|
'Trigger on': '触发时机',
|
||||||
'After record added': '新增数据后',
|
'After record added': '新增数据后',
|
||||||
'After record updated': '更新数据后',
|
'After record updated': '更新数据后',
|
||||||
'After record added or updated': '新增或更新数据后',
|
'After record added or updated': '新增或更新数据后',
|
||||||
'After record deleted': '删除数据后',
|
'After record deleted': '删除数据后',
|
||||||
'Changed fields': '发生变动的字段',
|
'Changed fields': '发生变动的字段',
|
||||||
'Select the fields which changed will trigger the event only': '只有被选中的某个字段发生变动时才会触发。如果不选择,则表示任何字段变动时都会触发。新增或删除数据时,任意字段都被认为发生变动。',
|
'Triggered only if one of the selected fields changes. If unselected, it means that it will be triggered when any field changes. When record is added or deleted, any field is considered to have been changed.': '只有被选中的某个字段发生变动时才会触发。如果不选择,则表示任何字段变动时都会触发。新增或删除数据时,任意字段都被认为发生变动。',
|
||||||
'Match condition': '满足条件',
|
'Only triggers when match conditions': '满足以下条件才触发',
|
||||||
|
|
||||||
'End': '结束',
|
'End': '结束',
|
||||||
|
|
||||||
@ -445,7 +445,6 @@ export default {
|
|||||||
'Failed': '失败',
|
'Failed': '失败',
|
||||||
'Canceled': '已取消',
|
'Canceled': '已取消',
|
||||||
|
|
||||||
'Node configuration': '配置节点',
|
|
||||||
'This node contains branches, deleting will also be preformed to them, are you sure?': '节点包含分支,将同时删除其所有分支下的子节点,确定继续?',
|
'This node contains branches, deleting will also be preformed to them, are you sure?': '节点包含分支,将同时删除其所有分支下的子节点,确定继续?',
|
||||||
|
|
||||||
'Control': '流程控制',
|
'Control': '流程控制',
|
||||||
@ -456,8 +455,28 @@ export default {
|
|||||||
'Calculation': '运算',
|
'Calculation': '运算',
|
||||||
'Configure calculation': '配置运算',
|
'Configure calculation': '配置运算',
|
||||||
'Calculation result': '运算结果',
|
'Calculation result': '运算结果',
|
||||||
|
'True': '真',
|
||||||
|
'False': '假',
|
||||||
|
|
||||||
|
'Condition': '条件判断',
|
||||||
|
'Mode': '模式',
|
||||||
|
'Reject on false': '通行模式',
|
||||||
|
'Branch results': '分支模式',
|
||||||
|
'Continue when result is "Yes"': '判断为“是”时继续',
|
||||||
|
'Make 2 branches for "Yes" and "No"': '判断结果分为“是”和“否”两个分支,分别继续',
|
||||||
|
'Conditions': '条件配置',
|
||||||
|
|
||||||
|
'Parallel': '并行',
|
||||||
|
'All succeeded': '全部成功',
|
||||||
|
'Any succeeded': '任意成功',
|
||||||
|
'Continue after all branches succeeded': '全部分支都成功后才能继续',
|
||||||
|
'Continue after any branch succeeded': '任意分支成功后就继续',
|
||||||
|
|
||||||
'Create record': '新增数据',
|
'Create record': '新增数据',
|
||||||
'Update record': '更新数据',
|
'Update record': '更新数据',
|
||||||
'Query record': '查询数据',
|
'Query record': '查询数据',
|
||||||
|
'Multiple records': '多条数据',
|
||||||
|
'Please select collection first': '请先选择数据表',
|
||||||
|
'Only update records matching conditions': '只更新满足条件的数据',
|
||||||
|
'Fields that are not assigned a value will be set to the default value, and those that do not have a default value are set to null.': '未被赋值的字段将被设置为默认值,没有默认值的设置为空值。'
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ export const WorkflowLink = () => {
|
|||||||
const { id } = useRecord();
|
const { id } = useRecord();
|
||||||
const { setVisible } = useActionContext();
|
const { setVisible } = useActionContext();
|
||||||
return (
|
return (
|
||||||
<Link to={`/admin/plugins/workflows/${id}`} onClick={() => setVisible(false)}>{t('Configure workflow')}</Link>
|
<Link to={`/admin/plugins/workflows/${id}`} onClick={() => setVisible(false)}>{t('Configure')}</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import { useFlowContext } from "./WorkflowCanvas";
|
|||||||
import { triggers } from "./triggers";
|
import { triggers } from "./triggers";
|
||||||
import { SchemaComponent, useCollectionManager, useCompile } from "..";
|
import { SchemaComponent, useCollectionManager, useCompile } from "..";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { t } from "i18next";
|
||||||
|
|
||||||
function NullRender() {
|
function NullRender() {
|
||||||
return null;
|
return null;
|
||||||
@ -107,10 +108,11 @@ const ConstantTypes = {
|
|||||||
title: '{{t("Boolean")}}',
|
title: '{{t("Boolean")}}',
|
||||||
value: 'boolean',
|
value: 'boolean',
|
||||||
component({ onChange, type, options, value }) {
|
component({ onChange, type, options, value }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<Select value={value} onChange={v => onChange({ value: v, type, options })}>
|
<Select value={value} onChange={v => onChange({ value: v, type, options })}>
|
||||||
<Select.Option value={true}>真</Select.Option>
|
<Select.Option value={true}>{t('True')}</Select.Option>
|
||||||
<Select.Option value={false}>假</Select.Option>
|
<Select.Option value={false}>{t('False')}</Select.Option>
|
||||||
</Select>
|
</Select>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -260,7 +262,7 @@ export function Operand({
|
|||||||
|
|
||||||
const { component, appendTypeValue } = Types[type] || {};
|
const { component, appendTypeValue } = Types[type] || {};
|
||||||
const VariableComponent = typeof component === 'function' ? component(operand) : NullRender;
|
const VariableComponent = typeof component === 'function' ? component(operand) : NullRender;
|
||||||
|
console.log(Types);
|
||||||
return (
|
return (
|
||||||
<div className={css`
|
<div className={css`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -283,7 +285,7 @@ export function Operand({
|
|||||||
return {
|
return {
|
||||||
label: compile(item.title),
|
label: compile(item.title),
|
||||||
value: item.value,
|
value: item.value,
|
||||||
children: options,
|
children: compile(options),
|
||||||
disabled: options && !options.length,
|
disabled: options && !options.length,
|
||||||
isLeaf: !options
|
isLeaf: !options
|
||||||
};
|
};
|
||||||
@ -305,7 +307,7 @@ export function Operand({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function Calculation({ calculator, operands = [], onChange }) {
|
export function Calculation({ calculator, operands = [], onChange }) {
|
||||||
const { t } = useTranslation();
|
const compile = useCompile();
|
||||||
return (
|
return (
|
||||||
<VariableTypesContext.Provider value={VariableTypes}>
|
<VariableTypesContext.Provider value={VariableTypes}>
|
||||||
<div className={css`
|
<div className={css`
|
||||||
@ -324,9 +326,9 @@ export function Calculation({ calculator, operands = [], onChange }) {
|
|||||||
<>
|
<>
|
||||||
<Select value={calculator} onChange={v => onChange({ operands, calculator: v })}>
|
<Select value={calculator} onChange={v => onChange({ operands, calculator: v })}>
|
||||||
{calculators.map(group => (
|
{calculators.map(group => (
|
||||||
<Select.OptGroup key={group.value} label={t(group.title)}>
|
<Select.OptGroup key={group.value} label={compile(group.title)}>
|
||||||
{group.children.map(item => (
|
{group.children.map(item => (
|
||||||
<Select.Option key={item.value} value={t(item.value)}>{item.name}</Select.Option>
|
<Select.Option key={item.value} value={item.value}>{compile(item.name)}</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select.OptGroup>
|
</Select.OptGroup>
|
||||||
))}
|
))}
|
||||||
@ -469,7 +471,7 @@ export const CollectionFieldset = observer(({ value, onChange }: any) => {
|
|||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
: <p>{t('Select collection')}</p>
|
: <p>{t('Please select collection first')}</p>
|
||||||
}
|
}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
|
@ -2,12 +2,13 @@ import React from "react";
|
|||||||
import { css, cx } from "@emotion/css";
|
import { css, cx } from "@emotion/css";
|
||||||
import { Button, Select, Tooltip } from "antd";
|
import { Button, Select, Tooltip } from "antd";
|
||||||
import { CloseCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
import { CloseCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||||
import { Trans } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { NodeDefaultView } from ".";
|
import { NodeDefaultView } from ".";
|
||||||
import { Branch, useFlowContext } from "../WorkflowCanvas";
|
import { Branch, useFlowContext } from "../WorkflowCanvas";
|
||||||
import { branchBlockClass, nodeSubtreeClass } from "../style";
|
import { branchBlockClass, nodeSubtreeClass } from "../style";
|
||||||
import { Calculation } from "../calculators";
|
import { Calculation } from "../calculators";
|
||||||
|
import { i18n } from "../../i18n";
|
||||||
// import { SchemaComponent } from "../../schema-component";
|
// import { SchemaComponent } from "../../schema-component";
|
||||||
|
|
||||||
function CalculationItem({ value, onChange, onRemove }) {
|
function CalculationItem({ value, onChange, onRemove }) {
|
||||||
@ -38,6 +39,7 @@ function CalculationItem({ value, onChange, onRemove }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function CalculationGroup({ value, onChange }) {
|
function CalculationGroup({ value, onChange }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { type = 'and', calculations = [] } = value;
|
const { type = 'and', calculations = [] } = value;
|
||||||
|
|
||||||
function onAddSingle() {
|
function onAddSingle() {
|
||||||
@ -113,8 +115,8 @@ function CalculationGroup({ value, onChange }) {
|
|||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
}
|
}
|
||||||
`} >
|
`} >
|
||||||
<a onClick={onAddSingle}>添加条件</a>
|
<a onClick={onAddSingle}>{t('Add condition')}</a>
|
||||||
<a onClick={onAddGroup}>添加条件组</a>
|
<a onClick={onAddGroup}>{t('Add condition group')}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -129,15 +131,17 @@ function CalculationConfig({ value, onChange }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(i18n.t('Collection name'));
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: '条件判断',
|
title: '{{t("Condition")}}',
|
||||||
type: 'condition',
|
type: 'condition',
|
||||||
group: 'control',
|
group: 'control',
|
||||||
fieldset: {
|
fieldset: {
|
||||||
'config.rejectOnFalse': {
|
'config.rejectOnFalse': {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
name: 'config.rejectOnFalse',
|
name: 'config.rejectOnFalse',
|
||||||
title: '模式',
|
title: '{{t("Mode")}}',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'Radio.Group',
|
'x-component': 'Radio.Group',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
@ -148,10 +152,10 @@ export default {
|
|||||||
value: true,
|
value: true,
|
||||||
label: (
|
label: (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title="判断为“是”时继续"
|
title={i18n.t('Continue when result is "Yes"')}
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
>
|
>
|
||||||
通行模式 <QuestionCircleOutlined style={{ color: '#999' }} />
|
{i18n.t('Reject on false')} <QuestionCircleOutlined style={{ color: '#999' }} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -159,10 +163,10 @@ export default {
|
|||||||
value: false,
|
value: false,
|
||||||
label: (
|
label: (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title="判断结果分为“是”和“否”两个分支,分别继续"
|
title={i18n.t('Make 2 branches for "Yes" and "No"')}
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
>
|
>
|
||||||
分支模式 <QuestionCircleOutlined style={{ color: '#999' }} />
|
{i18n.t('Branch results')} <QuestionCircleOutlined style={{ color: '#999' }} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -171,7 +175,7 @@ export default {
|
|||||||
'config.calculation': {
|
'config.calculation': {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
name: 'config.calculation',
|
name: 'config.calculation',
|
||||||
title: '条件配置',
|
title: '{{t("Conditions")}}',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'CalculationConfig',
|
'x-component': 'CalculationConfig',
|
||||||
}
|
}
|
||||||
@ -180,8 +184,8 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
{ label: '通行模式', key: 'rejectOnFalse', value: { rejectOnFalse: true } },
|
{ label: i18n.t('Reject on false'), key: 'rejectOnFalse', value: { rejectOnFalse: true } },
|
||||||
{ label: '分支模式', key: 'branch', value: { rejectOnFalse: false } }
|
{ label: i18n.t('Branch results'), key: 'branch', value: { rejectOnFalse: false } }
|
||||||
],
|
],
|
||||||
render(data) {
|
render(data) {
|
||||||
const { id, config: { rejectOnFalse } } = data;
|
const { id, config: { rejectOnFalse } } = data;
|
||||||
@ -210,7 +214,7 @@ export default {
|
|||||||
height: 2em;
|
height: 2em;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
|
||||||
:before,:after{
|
> span{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(1.5em - 1px);
|
top: calc(1.5em - 1px);
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
@ -218,18 +222,11 @@ export default {
|
|||||||
background-color: #f0f2f5;
|
background-color: #f0f2f5;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:before{
|
|
||||||
content: "否";
|
|
||||||
right: 4em;
|
|
||||||
}
|
|
||||||
|
|
||||||
:after{
|
|
||||||
content: "是";
|
|
||||||
left: 4em;
|
|
||||||
}
|
|
||||||
`}
|
`}
|
||||||
/>
|
>
|
||||||
|
<span className={css`right: 4em;`}>{i18n.t('No')}</span>
|
||||||
|
<span className={css`left: 4em;`}>{i18n.t('Yes')}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</NodeDefaultView>
|
</NodeDefaultView>
|
||||||
|
@ -6,7 +6,7 @@ import { Button, Modal, Tag } from 'antd';
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { SchemaComponent, useActionContext, useAPIClient, useCollection, useCompile, useRequest, useResourceActionContext } from '../..';
|
import { SchemaComponent, useActionContext, useAPIClient, useCollection, useCompile, useRequest, useResourceActionContext } from '../..';
|
||||||
import { nodeBlockClass, nodeCardClass, nodeClass, nodeHeaderClass, nodeTitleClass } from '../style';
|
import { nodeBlockClass, nodeCardClass, nodeClass, nodeHeaderClass, nodeMetaClass, nodeTitleClass } from '../style';
|
||||||
import { AddButton, useFlowContext } from '../WorkflowCanvas';
|
import { AddButton, useFlowContext } from '../WorkflowCanvas';
|
||||||
|
|
||||||
import calculation from './calculation';
|
import calculation from './calculation';
|
||||||
@ -156,8 +156,10 @@ export function NodeDefaultView(props) {
|
|||||||
<div className={cx(nodeClass, `workflow-node-type-${data.type}`)}>
|
<div className={cx(nodeClass, `workflow-node-type-${data.type}`)}>
|
||||||
<div className={cx(nodeCardClass)}>
|
<div className={cx(nodeCardClass)}>
|
||||||
<div className={cx(nodeHeaderClass)}>
|
<div className={cx(nodeHeaderClass)}>
|
||||||
<h4 className={cx(nodeTitleClass)}>
|
<div className={cx(nodeMetaClass)}>
|
||||||
<Tag>{compile(instruction.title)}</Tag>
|
<Tag>{compile(instruction.title)}</Tag>
|
||||||
|
</div>
|
||||||
|
<h4 className={cx(nodeTitleClass)}>
|
||||||
<strong>{data.title}</strong>
|
<strong>{data.title}</strong>
|
||||||
<span className="workflow-node-id">#{data.id}</span>
|
<span className="workflow-node-id">#{data.id}</span>
|
||||||
</h4>
|
</h4>
|
||||||
@ -172,7 +174,7 @@ export function NodeDefaultView(props) {
|
|||||||
view: instruction.view,
|
view: instruction.view,
|
||||||
config: {
|
config: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{t("Node configuration")}}',
|
title: '{{t("Configure")}}',
|
||||||
'x-component': 'Action.Link',
|
'x-component': 'Action.Link',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
@ -180,7 +182,7 @@ export function NodeDefaultView(props) {
|
|||||||
properties: {
|
properties: {
|
||||||
drawer: {
|
drawer: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{t("Node configuration")}}',
|
title: '{{t("Configure")}}',
|
||||||
'x-component': 'Action.Drawer',
|
'x-component': 'Action.Drawer',
|
||||||
'x-decorator': 'Form',
|
'x-decorator': 'Form',
|
||||||
'x-decorator-props': {
|
'x-decorator-props': {
|
||||||
|
@ -6,17 +6,19 @@ import { NodeDefaultView } from ".";
|
|||||||
import { Branch, useFlowContext } from "../WorkflowCanvas";
|
import { Branch, useFlowContext } from "../WorkflowCanvas";
|
||||||
import { branchBlockClass, nodeSubtreeClass } from "../style";
|
import { branchBlockClass, nodeSubtreeClass } from "../style";
|
||||||
import { Button, Tooltip } from "antd";
|
import { Button, Tooltip } from "antd";
|
||||||
|
import { i18n } from "../../i18n";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
// import { SchemaComponent } from "../../schema-component";
|
// import { SchemaComponent } from "../../schema-component";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: '并行',
|
title: '{{t("Parallel")}}',
|
||||||
type: 'parallel',
|
type: 'parallel',
|
||||||
group: 'control',
|
group: 'control',
|
||||||
fieldset: {
|
fieldset: {
|
||||||
'config.mode': {
|
'config.mode': {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
name: 'config.mode',
|
name: 'config.mode',
|
||||||
title: '模式',
|
title: '{{t("Mode")}}',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'Radio.Group',
|
'x-component': 'Radio.Group',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
@ -26,10 +28,10 @@ export default {
|
|||||||
value: 'all',
|
value: 'all',
|
||||||
label: (
|
label: (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title="全部分支都成功后才能继续"
|
title={i18n.t('Continue after all branches succeeded')}
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
>
|
>
|
||||||
全部成功 <QuestionCircleOutlined style={{ color: '#999' }} />
|
{i18n.t('All succeeded')} <QuestionCircleOutlined style={{ color: '#999' }} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -37,10 +39,10 @@ export default {
|
|||||||
value: 'any',
|
value: 'any',
|
||||||
label: (
|
label: (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title="任意分支成功后就继续"
|
title="Continue after any branch succeeded"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
>
|
>
|
||||||
任意成功 <QuestionCircleOutlined style={{ color: '#999' }} />
|
{i18n.t('Any succeeded')} <QuestionCircleOutlined style={{ color: '#999' }} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -54,6 +56,7 @@ export default {
|
|||||||
},
|
},
|
||||||
render(data) {
|
render(data) {
|
||||||
const { id, config: { mode } } = data;
|
const { id, config: { mode } } = data;
|
||||||
|
const { t } = useTranslation();
|
||||||
const { nodes } = useFlowContext();
|
const { nodes } = useFlowContext();
|
||||||
const branches = nodes.reduce((result, node) => {
|
const branches = nodes.reduce((result, node) => {
|
||||||
if (node.upstreamId === id && node.branchIndex != null) {
|
if (node.upstreamId === id && node.branchIndex != null) {
|
||||||
@ -108,7 +111,7 @@ export default {
|
|||||||
height: 2em;
|
height: 2em;
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<Tooltip title="添加分支">
|
<Tooltip title={t('Add branch')}>
|
||||||
<Button
|
<Button
|
||||||
icon={<PlusOutlined />}
|
icon={<PlusOutlined />}
|
||||||
className={css`
|
className={css`
|
||||||
|
@ -16,7 +16,7 @@ export default {
|
|||||||
'config.collection': collection,
|
'config.collection': collection,
|
||||||
'config.multiple': {
|
'config.multiple': {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
title: '多条数据',
|
title: '{{t("Multiple records")}}',
|
||||||
name: 'config.multiple',
|
name: 'config.multiple',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'Checkbox',
|
'x-component': 'Checkbox',
|
||||||
|
@ -14,7 +14,10 @@ export default {
|
|||||||
title: '',
|
title: '',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
properties: {
|
properties: {
|
||||||
filter,
|
filter: {
|
||||||
|
...filter,
|
||||||
|
title: '{{t("Only update records matching conditions")}}',
|
||||||
|
},
|
||||||
values
|
values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export const collection = {
|
|||||||
|
|
||||||
export const values = {
|
export const values = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
title: '{{t("Form values")}}',
|
title: '{{t("Fields values")}}',
|
||||||
name: 'config.params.values',
|
name: 'config.params.values',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-decorator-props': {
|
'x-decorator-props': {
|
||||||
@ -24,7 +24,8 @@ export const values = {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
'x-component': 'CollectionFieldset'
|
'x-component': 'CollectionFieldset',
|
||||||
|
description: '{{t("Fields that are not assigned a value will be set to the default value, and those that do not have a default value are set to null.")}}',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const filter = {
|
export const filter = {
|
||||||
|
@ -225,7 +225,7 @@ export const workflowSchema: ISchema = {
|
|||||||
},
|
},
|
||||||
executions: {
|
executions: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{t("Executions")}}',
|
title: '{{t("Execution History")}}',
|
||||||
'x-component': 'Action.Link',
|
'x-component': 'Action.Link',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
@ -233,7 +233,7 @@ export const workflowSchema: ISchema = {
|
|||||||
properties: {
|
properties: {
|
||||||
drawer: {
|
drawer: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{t("Executions")}}',
|
title: '{{t("Execution History")}}',
|
||||||
'x-component': 'Action.Drawer',
|
'x-component': 'Action.Drawer',
|
||||||
properties: executionSchema
|
properties: executionSchema
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,10 @@ export const nodeHeaderClass = css`
|
|||||||
position: relative;
|
position: relative;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const nodeMetaClass = css`
|
||||||
|
margin-bottom: .5em;
|
||||||
|
`;
|
||||||
|
|
||||||
export const nodeTitleClass = css`
|
export const nodeTitleClass = css`
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ function useCollectionFieldsDataSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: '{{t("Model event")}}',
|
title: '{{t("Collection event")}}',
|
||||||
type: 'model',
|
type: 'collection',
|
||||||
fieldset: {
|
fieldset: {
|
||||||
'config.collection': collection,
|
'config.collection': collection,
|
||||||
'config.mode': {
|
'config.mode': {
|
||||||
@ -50,13 +50,14 @@ export default {
|
|||||||
{ value: 3, label: '{{t("After record added or updated")}}' },
|
{ value: 3, label: '{{t("After record added or updated")}}' },
|
||||||
{ value: 4, label: '{{t("After record deleted")}}' }
|
{ value: 4, label: '{{t("After record deleted")}}' }
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
required: true
|
||||||
},
|
},
|
||||||
'config.changed': {
|
'config.changed': {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
name: 'changed',
|
name: 'changed',
|
||||||
title: '{{t("Changed fields")}}',
|
title: '{{t("Changed fields")}}',
|
||||||
description: '{{t("Select the fields which changed will trigger the event only")}}',
|
description: '{{t("Triggered only if one of the selected fields changes. If unselected, it means that it will be triggered when any field changes. When record is added or deleted, any field is considered to have been changed.")}}',
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'Select',
|
'x-component': 'Select',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
@ -69,7 +70,7 @@ export default {
|
|||||||
'config.condition': {
|
'config.condition': {
|
||||||
...filter,
|
...filter,
|
||||||
name: 'config.condition',
|
name: 'config.condition',
|
||||||
title: '{{t("Match condition")}}',
|
title: '{{t("Only triggers when match conditions")}}'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scope: {
|
scope: {
|
@ -4,8 +4,10 @@ import { cx } from "@emotion/css";
|
|||||||
import { Registry } from "@nocobase/utils";
|
import { Registry } from "@nocobase/utils";
|
||||||
|
|
||||||
import { SchemaComponent, useActionContext, useAPIClient, useCompile, useRecord, useRequest, useResourceActionContext } from '../../';
|
import { SchemaComponent, useActionContext, useAPIClient, useCompile, useRecord, useRequest, useResourceActionContext } from '../../';
|
||||||
import model from './model';
|
import collection from './collection';
|
||||||
import { nodeCardClass } from "../style";
|
import { nodeCardClass, nodeMetaClass } from "../style";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Tag } from "antd";
|
||||||
|
|
||||||
|
|
||||||
function useUpdateConfigAction() {
|
function useUpdateConfigAction() {
|
||||||
@ -42,9 +44,10 @@ export interface Trigger {
|
|||||||
|
|
||||||
export const triggers = new Registry<Trigger>();
|
export const triggers = new Registry<Trigger>();
|
||||||
|
|
||||||
triggers.register(model.type, model);
|
triggers.register(collection.type, collection);
|
||||||
|
|
||||||
export const TriggerConfig = () => {
|
export const TriggerConfig = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
const { data } = useResourceActionContext();
|
const { data } = useResourceActionContext();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
@ -54,17 +57,20 @@ export const TriggerConfig = () => {
|
|||||||
const { title, fieldset, scope } = triggers.get(type);
|
const { title, fieldset, scope } = triggers.get(type);
|
||||||
return (
|
return (
|
||||||
<div className={cx(nodeCardClass)}>
|
<div className={cx(nodeCardClass)}>
|
||||||
|
<div className={cx(nodeMetaClass)}>
|
||||||
|
<Tag color="gold">{t('Trigger')}</Tag>
|
||||||
|
</div>
|
||||||
<h4>{compile(title)}</h4>
|
<h4>{compile(title)}</h4>
|
||||||
<SchemaComponent
|
<SchemaComponent
|
||||||
schema={{
|
schema={{
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{t("Trigger configuration")}}',
|
title: '{{t("Configure")}}',
|
||||||
'x-component': 'Action.Link',
|
'x-component': 'Action.Link',
|
||||||
name: 'drawer',
|
name: 'drawer',
|
||||||
properties: {
|
properties: {
|
||||||
drawer: {
|
drawer: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{t("Trigger configuration")}}',
|
title: '{{t("Configure")}}',
|
||||||
'x-component': 'Action.Drawer',
|
'x-component': 'Action.Drawer',
|
||||||
'x-decorator': 'Form',
|
'x-decorator': 'Form',
|
||||||
'x-decorator-props': {
|
'x-decorator-props': {
|
||||||
|
@ -22,7 +22,7 @@ describe('execution', () => {
|
|||||||
workflow = await WorkflowModel.create({
|
workflow = await WorkflowModel.create({
|
||||||
title: 'test workflow',
|
title: 'test workflow',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
type: 'model',
|
type: 'collection',
|
||||||
config: {
|
config: {
|
||||||
mode: 1,
|
mode: 1,
|
||||||
collection: 'posts'
|
collection: 'posts'
|
||||||
|
@ -21,7 +21,7 @@ describe('workflow > instructions > calculation', () => {
|
|||||||
workflow = await WorkflowModel.create({
|
workflow = await WorkflowModel.create({
|
||||||
title: 'test workflow',
|
title: 'test workflow',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
type: 'model',
|
type: 'collection',
|
||||||
config: {
|
config: {
|
||||||
mode: 1,
|
mode: 1,
|
||||||
collection: 'posts'
|
collection: 'posts'
|
||||||
|
@ -22,7 +22,7 @@ describe('workflow > instructions > condition', () => {
|
|||||||
workflow = await WorkflowModel.create({
|
workflow = await WorkflowModel.create({
|
||||||
title: 'test workflow',
|
title: 'test workflow',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
type: 'model',
|
type: 'collection',
|
||||||
config: {
|
config: {
|
||||||
mode: 1,
|
mode: 1,
|
||||||
collection: 'posts'
|
collection: 'posts'
|
||||||
|
@ -21,7 +21,7 @@ describe('workflow > instructions > create', () => {
|
|||||||
workflow = await WorkflowModel.create({
|
workflow = await WorkflowModel.create({
|
||||||
title: 'test workflow',
|
title: 'test workflow',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
type: 'model',
|
type: 'collection',
|
||||||
config: {
|
config: {
|
||||||
mode: 1,
|
mode: 1,
|
||||||
collection: 'posts'
|
collection: 'posts'
|
||||||
|
@ -21,7 +21,7 @@ describe('workflow > instructions > destroy', () => {
|
|||||||
workflow = await WorkflowModel.create({
|
workflow = await WorkflowModel.create({
|
||||||
title: 'test workflow',
|
title: 'test workflow',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
type: 'model',
|
type: 'collection',
|
||||||
config: {
|
config: {
|
||||||
mode: 1,
|
mode: 1,
|
||||||
collection: 'posts'
|
collection: 'posts'
|
||||||
|
@ -21,7 +21,7 @@ describe('workflow > instructions > query', () => {
|
|||||||
workflow = await WorkflowModel.create({
|
workflow = await WorkflowModel.create({
|
||||||
title: 'test workflow',
|
title: 'test workflow',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
type: 'model',
|
type: 'collection',
|
||||||
config: {
|
config: {
|
||||||
mode: 1,
|
mode: 1,
|
||||||
collection: 'posts'
|
collection: 'posts'
|
||||||
|
@ -21,7 +21,7 @@ describe('workflow > instructions > update', () => {
|
|||||||
workflow = await WorkflowModel.create({
|
workflow = await WorkflowModel.create({
|
||||||
title: 'test workflow',
|
title: 'test workflow',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
type: 'model',
|
type: 'collection',
|
||||||
config: {
|
config: {
|
||||||
mode: 1,
|
mode: 1,
|
||||||
collection: 'posts'
|
collection: 'posts'
|
||||||
|
@ -37,7 +37,7 @@ function bindHandler(this: WorkflowModel, callback: Function) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'model',
|
name: 'collection',
|
||||||
on(this: WorkflowModel, callback: Function) {
|
on(this: WorkflowModel, callback: Function) {
|
||||||
const { database } = <typeof WorkflowModel>this.constructor;
|
const { database } = <typeof WorkflowModel>this.constructor;
|
||||||
const { collection, mode } = this.config;
|
const { collection, mode } = this.config;
|
||||||
@ -47,7 +47,9 @@ export default {
|
|||||||
}
|
}
|
||||||
// TODO: duplication when mode change should be considered
|
// TODO: duplication when mode change should be considered
|
||||||
for (let [key, event] of MODE_BITMAP_EVENTS.entries()) {
|
for (let [key, event] of MODE_BITMAP_EVENTS.entries()) {
|
||||||
if (mode & key) {
|
if (mode & key
|
||||||
|
&& !Collection.model.options.hooks[event]?.find(item => item.name && item.name === this.getHookId())
|
||||||
|
) {
|
||||||
Collection.model.addHook(event, this.getHookId(), bindHandler.call(this, callback));
|
Collection.model.addHook(event, this.getHookId(), bindHandler.call(this, callback));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { Registry } from '@nocobase/utils';
|
import { Registry } from '@nocobase/utils';
|
||||||
import WorkflowModel from '../models/Workflow';
|
import WorkflowModel from '../models/Workflow';
|
||||||
import modelTrigger from './model';
|
import collectionlTrigger from './collection';
|
||||||
|
|
||||||
export interface Trigger {
|
export interface Trigger {
|
||||||
name: string;
|
name: string;
|
||||||
@ -12,4 +12,4 @@ export const triggers = new Registry<Trigger>();
|
|||||||
|
|
||||||
export default triggers;
|
export default triggers;
|
||||||
|
|
||||||
triggers.register(modelTrigger.name, modelTrigger);
|
triggers.register(collectionlTrigger.name, collectionlTrigger);
|
||||||
|
Loading…
Reference in New Issue
Block a user