diff --git a/packages/core/client/src/locale/en_US.ts b/packages/core/client/src/locale/en_US.ts
index 150f3eb9c..2c0873982 100644
--- a/packages/core/client/src/locale/en_US.ts
+++ b/packages/core/client/src/locale/en_US.ts
@@ -280,5 +280,8 @@ export default {
"Add card": "Add card",
"edit title": "Edit Title",
"Turn the page": "Turn the page",
- "Others": "Others"
+ "Others": "Others",
+
+ // workflows
+ 'Execution History': 'History',
}
diff --git a/packages/core/client/src/locale/zh_CN.ts b/packages/core/client/src/locale/zh_CN.ts
index ab0a13d89..1009046dc 100644
--- a/packages/core/client/src/locale/zh_CN.ts
+++ b/packages/core/client/src/locale/zh_CN.ts
@@ -318,6 +318,7 @@ export default {
'Skip required validation': '跳过必填校验',
'Form values': '表单值',
+ 'Fields values': '字段值',
'When submitting the following fields, the saved values are': '提交以下字段时,保存的值为',
'After successful submission': '提交成功后',
'Then': '然后',
@@ -407,25 +408,24 @@ export default {
// plugins/workflow
'Workflow': '工作流',
- 'Configure workflow': '流程配置',
- 'Executions': '执行历史',
+ 'Execution History': '执行历史',
'Trigger type': '触发方式',
'Description': '描述',
'Status': '状态',
'Enabled': '启用',
'Disabled': '禁用',
- 'Trigger configuration': '触发器配置',
'Load failed': '加载失败',
- 'Model event': '数据表事件',
+ 'Trigger': '触发器',
+ 'Collection event': '数据表事件',
'Trigger on': '触发时机',
'After record added': '新增数据后',
'After record updated': '更新数据后',
'After record added or updated': '新增或更新数据后',
'After record deleted': '删除数据后',
'Changed fields': '发生变动的字段',
- 'Select the fields which changed will trigger the event only': '只有被选中的某个字段发生变动时才会触发。如果不选择,则表示任何字段变动时都会触发。新增或删除数据时,任意字段都被认为发生变动。',
- 'Match condition': '满足条件',
+ '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.': '只有被选中的某个字段发生变动时才会触发。如果不选择,则表示任何字段变动时都会触发。新增或删除数据时,任意字段都被认为发生变动。',
+ 'Only triggers when match conditions': '满足以下条件才触发',
'End': '结束',
@@ -445,7 +445,6 @@ export default {
'Failed': '失败',
'Canceled': '已取消',
- 'Node configuration': '配置节点',
'This node contains branches, deleting will also be preformed to them, are you sure?': '节点包含分支,将同时删除其所有分支下的子节点,确定继续?',
'Control': '流程控制',
@@ -456,8 +455,28 @@ export default {
'Calculation': '运算',
'Configure calculation': '配置运算',
'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': '新增数据',
'Update 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.': '未被赋值的字段将被设置为默认值,没有默认值的设置为空值。'
}
diff --git a/packages/core/client/src/workflow/WorkflowLink.tsx b/packages/core/client/src/workflow/WorkflowLink.tsx
index 6ab518e07..499a220a1 100644
--- a/packages/core/client/src/workflow/WorkflowLink.tsx
+++ b/packages/core/client/src/workflow/WorkflowLink.tsx
@@ -9,6 +9,6 @@ export const WorkflowLink = () => {
const { id } = useRecord();
const { setVisible } = useActionContext();
return (
- setVisible(false)}>{t('Configure workflow')}
+ setVisible(false)}>{t('Configure')}
);
}
diff --git a/packages/core/client/src/workflow/calculators.tsx b/packages/core/client/src/workflow/calculators.tsx
index 5c85c5e57..94047509d 100644
--- a/packages/core/client/src/workflow/calculators.tsx
+++ b/packages/core/client/src/workflow/calculators.tsx
@@ -10,6 +10,7 @@ import { useFlowContext } from "./WorkflowCanvas";
import { triggers } from "./triggers";
import { SchemaComponent, useCollectionManager, useCompile } from "..";
import { useTranslation } from "react-i18next";
+import { t } from "i18next";
function NullRender() {
return null;
@@ -107,10 +108,11 @@ const ConstantTypes = {
title: '{{t("Boolean")}}',
value: 'boolean',
component({ onChange, type, options, value }) {
+ const { t } = useTranslation();
return (
);
},
@@ -260,7 +262,7 @@ export function Operand({
const { component, appendTypeValue } = Types[type] || {};
const VariableComponent = typeof component === 'function' ? component(operand) : NullRender;
-
+ console.log(Types);
return (
);
@@ -129,15 +131,17 @@ function CalculationConfig({ value, onChange }) {
);
}
+console.log(i18n.t('Collection name'));
+
export default {
- title: '条件判断',
+ title: '{{t("Condition")}}',
type: 'condition',
group: 'control',
fieldset: {
'config.rejectOnFalse': {
type: 'boolean',
name: 'config.rejectOnFalse',
- title: '模式',
+ title: '{{t("Mode")}}',
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {
@@ -148,10 +152,10 @@ export default {
value: true,
label: (
- 通行模式
+ {i18n.t('Reject on false')}
)
},
@@ -159,10 +163,10 @@ export default {
value: false,
label: (
- 分支模式
+ {i18n.t('Branch results')}
)
}
@@ -171,7 +175,7 @@ export default {
'config.calculation': {
type: 'string',
name: 'config.calculation',
- title: '条件配置',
+ title: '{{t("Conditions")}}',
'x-decorator': 'FormItem',
'x-component': 'CalculationConfig',
}
@@ -180,8 +184,8 @@ export default {
},
options: [
- { label: '通行模式', key: 'rejectOnFalse', value: { rejectOnFalse: true } },
- { label: '分支模式', key: 'branch', value: { rejectOnFalse: false } }
+ { label: i18n.t('Reject on false'), key: 'rejectOnFalse', value: { rejectOnFalse: true } },
+ { label: i18n.t('Branch results'), key: 'branch', value: { rejectOnFalse: false } }
],
render(data) {
const { id, config: { rejectOnFalse } } = data;
@@ -210,7 +214,7 @@ export default {
height: 2em;
overflow: visible;
- :before,:after{
+ > span{
position: absolute;
top: calc(1.5em - 1px);
line-height: 1em;
@@ -218,18 +222,11 @@ export default {
background-color: #f0f2f5;
padding: 1px;
}
-
- :before{
- content: "否";
- right: 4em;
- }
-
- :after{
- content: "是";
- left: 4em;
- }
`}
- />
+ >
+ {i18n.t('No')}
+ {i18n.t('Yes')}
+
)}
diff --git a/packages/core/client/src/workflow/nodes/index.tsx b/packages/core/client/src/workflow/nodes/index.tsx
index 5a19a3f67..cdaa9a706 100644
--- a/packages/core/client/src/workflow/nodes/index.tsx
+++ b/packages/core/client/src/workflow/nodes/index.tsx
@@ -6,7 +6,7 @@ import { Button, Modal, Tag } from 'antd';
import React, { useContext } from 'react';
import { useTranslation } from 'react-i18next';
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 calculation from './calculation';
@@ -156,8 +156,10 @@ export function NodeDefaultView(props) {
-
+
{compile(instruction.title)}
+
+
{data.title}
#{data.id}
@@ -172,7 +174,7 @@ export function NodeDefaultView(props) {
view: instruction.view,
config: {
type: 'void',
- title: '{{t("Node configuration")}}',
+ title: '{{t("Configure")}}',
'x-component': 'Action.Link',
'x-component-props': {
type: 'primary',
@@ -180,7 +182,7 @@ export function NodeDefaultView(props) {
properties: {
drawer: {
type: 'void',
- title: '{{t("Node configuration")}}',
+ title: '{{t("Configure")}}',
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
'x-decorator-props': {
diff --git a/packages/core/client/src/workflow/nodes/parallel.tsx b/packages/core/client/src/workflow/nodes/parallel.tsx
index 72ef90fc0..10f9a86d6 100644
--- a/packages/core/client/src/workflow/nodes/parallel.tsx
+++ b/packages/core/client/src/workflow/nodes/parallel.tsx
@@ -6,17 +6,19 @@ import { NodeDefaultView } from ".";
import { Branch, useFlowContext } from "../WorkflowCanvas";
import { branchBlockClass, nodeSubtreeClass } from "../style";
import { Button, Tooltip } from "antd";
+import { i18n } from "../../i18n";
+import { useTranslation } from "react-i18next";
// import { SchemaComponent } from "../../schema-component";
export default {
- title: '并行',
+ title: '{{t("Parallel")}}',
type: 'parallel',
group: 'control',
fieldset: {
'config.mode': {
type: 'string',
name: 'config.mode',
- title: '模式',
+ title: '{{t("Mode")}}',
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {
@@ -26,10 +28,10 @@ export default {
value: 'all',
label: (
- 全部成功
+ {i18n.t('All succeeded')}
)
},
@@ -37,10 +39,10 @@ export default {
value: 'any',
label: (
- 任意成功
+ {i18n.t('Any succeeded')}
)
},
@@ -54,6 +56,7 @@ export default {
},
render(data) {
const { id, config: { mode } } = data;
+ const { t } = useTranslation();
const { nodes } = useFlowContext();
const branches = nodes.reduce((result, node) => {
if (node.upstreamId === id && node.branchIndex != null) {
@@ -108,7 +111,7 @@ export default {
height: 2em;
`}
>
-
+
}
className={css`
diff --git a/packages/core/client/src/workflow/nodes/query.tsx b/packages/core/client/src/workflow/nodes/query.tsx
index 9679c74e6..90ed8eddd 100644
--- a/packages/core/client/src/workflow/nodes/query.tsx
+++ b/packages/core/client/src/workflow/nodes/query.tsx
@@ -16,7 +16,7 @@ export default {
'config.collection': collection,
'config.multiple': {
type: 'boolean',
- title: '多条数据',
+ title: '{{t("Multiple records")}}',
name: 'config.multiple',
'x-decorator': 'FormItem',
'x-component': 'Checkbox',
diff --git a/packages/core/client/src/workflow/nodes/update.tsx b/packages/core/client/src/workflow/nodes/update.tsx
index 18b48228a..2dbd9e911 100644
--- a/packages/core/client/src/workflow/nodes/update.tsx
+++ b/packages/core/client/src/workflow/nodes/update.tsx
@@ -14,7 +14,10 @@ export default {
title: '',
'x-decorator': 'FormItem',
properties: {
- filter,
+ filter: {
+ ...filter,
+ title: '{{t("Only update records matching conditions")}}',
+ },
values
}
}
diff --git a/packages/core/client/src/workflow/schemas/collection.ts b/packages/core/client/src/workflow/schemas/collection.ts
index 0c579576b..891668fa4 100644
--- a/packages/core/client/src/workflow/schemas/collection.ts
+++ b/packages/core/client/src/workflow/schemas/collection.ts
@@ -15,7 +15,7 @@ export const collection = {
export const values = {
type: 'object',
- title: '{{t("Form values")}}',
+ title: '{{t("Fields values")}}',
name: 'config.params.values',
'x-decorator': 'FormItem',
'x-decorator-props': {
@@ -24,7 +24,8 @@ export const values = {
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 = {
diff --git a/packages/core/client/src/workflow/schemas/workflows.ts b/packages/core/client/src/workflow/schemas/workflows.ts
index cef85f6cf..a5f0ad0fa 100644
--- a/packages/core/client/src/workflow/schemas/workflows.ts
+++ b/packages/core/client/src/workflow/schemas/workflows.ts
@@ -225,7 +225,7 @@ export const workflowSchema: ISchema = {
},
executions: {
type: 'void',
- title: '{{t("Executions")}}',
+ title: '{{t("Execution History")}}',
'x-component': 'Action.Link',
'x-component-props': {
type: 'primary',
@@ -233,7 +233,7 @@ export const workflowSchema: ISchema = {
properties: {
drawer: {
type: 'void',
- title: '{{t("Executions")}}',
+ title: '{{t("Execution History")}}',
'x-component': 'Action.Drawer',
properties: executionSchema
}
diff --git a/packages/core/client/src/workflow/style.tsx b/packages/core/client/src/workflow/style.tsx
index 0036a3b71..90ad958fa 100644
--- a/packages/core/client/src/workflow/style.tsx
+++ b/packages/core/client/src/workflow/style.tsx
@@ -133,6 +133,10 @@ export const nodeHeaderClass = css`
position: relative;
`;
+export const nodeMetaClass = css`
+ margin-bottom: .5em;
+`;
+
export const nodeTitleClass = css`
font-weight: normal;
diff --git a/packages/core/client/src/workflow/triggers/model.tsx b/packages/core/client/src/workflow/triggers/collection.tsx
similarity index 88%
rename from packages/core/client/src/workflow/triggers/model.tsx
rename to packages/core/client/src/workflow/triggers/collection.tsx
index 2c933b9a4..05add81e8 100644
--- a/packages/core/client/src/workflow/triggers/model.tsx
+++ b/packages/core/client/src/workflow/triggers/collection.tsx
@@ -33,8 +33,8 @@ function useCollectionFieldsDataSource() {
}
export default {
- title: '{{t("Model event")}}',
- type: 'model',
+ title: '{{t("Collection event")}}',
+ type: 'collection',
fieldset: {
'config.collection': collection,
'config.mode': {
@@ -50,13 +50,14 @@ export default {
{ value: 3, label: '{{t("After record added or updated")}}' },
{ value: 4, label: '{{t("After record deleted")}}' }
]
- }
+ },
+ required: true
},
'config.changed': {
type: 'array',
name: 'changed',
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-component': 'Select',
'x-component-props': {
@@ -69,7 +70,7 @@ export default {
'config.condition': {
...filter,
name: 'config.condition',
- title: '{{t("Match condition")}}',
+ title: '{{t("Only triggers when match conditions")}}'
}
},
scope: {
diff --git a/packages/core/client/src/workflow/triggers/index.tsx b/packages/core/client/src/workflow/triggers/index.tsx
index 8721f2871..53bc06e23 100644
--- a/packages/core/client/src/workflow/triggers/index.tsx
+++ b/packages/core/client/src/workflow/triggers/index.tsx
@@ -4,8 +4,10 @@ import { cx } from "@emotion/css";
import { Registry } from "@nocobase/utils";
import { SchemaComponent, useActionContext, useAPIClient, useCompile, useRecord, useRequest, useResourceActionContext } from '../../';
-import model from './model';
-import { nodeCardClass } from "../style";
+import collection from './collection';
+import { nodeCardClass, nodeMetaClass } from "../style";
+import { useTranslation } from "react-i18next";
+import { Tag } from "antd";
function useUpdateConfigAction() {
@@ -42,9 +44,10 @@ export interface Trigger {
export const triggers = new Registry();
-triggers.register(model.type, model);
+triggers.register(collection.type, collection);
export const TriggerConfig = () => {
+ const { t } = useTranslation();
const compile = useCompile();
const { data } = useResourceActionContext();
if (!data) {
@@ -54,17 +57,20 @@ export const TriggerConfig = () => {
const { title, fieldset, scope } = triggers.get(type);
return (
+
+ {t('Trigger')}
+
{compile(title)}
{
workflow = await WorkflowModel.create({
title: 'test workflow',
enabled: true,
- type: 'model',
+ type: 'collection',
config: {
mode: 1,
collection: 'posts'
diff --git a/packages/plugins/workflow/src/__tests__/instructions/calculation.test.ts b/packages/plugins/workflow/src/__tests__/instructions/calculation.test.ts
index 24ede4d76..94faafc4f 100644
--- a/packages/plugins/workflow/src/__tests__/instructions/calculation.test.ts
+++ b/packages/plugins/workflow/src/__tests__/instructions/calculation.test.ts
@@ -21,7 +21,7 @@ describe('workflow > instructions > calculation', () => {
workflow = await WorkflowModel.create({
title: 'test workflow',
enabled: true,
- type: 'model',
+ type: 'collection',
config: {
mode: 1,
collection: 'posts'
diff --git a/packages/plugins/workflow/src/__tests__/instructions/condition.test.ts b/packages/plugins/workflow/src/__tests__/instructions/condition.test.ts
index d0375a5b9..3f9a4f726 100644
--- a/packages/plugins/workflow/src/__tests__/instructions/condition.test.ts
+++ b/packages/plugins/workflow/src/__tests__/instructions/condition.test.ts
@@ -22,7 +22,7 @@ describe('workflow > instructions > condition', () => {
workflow = await WorkflowModel.create({
title: 'test workflow',
enabled: true,
- type: 'model',
+ type: 'collection',
config: {
mode: 1,
collection: 'posts'
diff --git a/packages/plugins/workflow/src/__tests__/instructions/create.test.ts b/packages/plugins/workflow/src/__tests__/instructions/create.test.ts
index 1cd51b404..3e4316c46 100644
--- a/packages/plugins/workflow/src/__tests__/instructions/create.test.ts
+++ b/packages/plugins/workflow/src/__tests__/instructions/create.test.ts
@@ -21,7 +21,7 @@ describe('workflow > instructions > create', () => {
workflow = await WorkflowModel.create({
title: 'test workflow',
enabled: true,
- type: 'model',
+ type: 'collection',
config: {
mode: 1,
collection: 'posts'
diff --git a/packages/plugins/workflow/src/__tests__/instructions/destroy.test.ts b/packages/plugins/workflow/src/__tests__/instructions/destroy.test.ts
index 3019fabde..ec156022f 100644
--- a/packages/plugins/workflow/src/__tests__/instructions/destroy.test.ts
+++ b/packages/plugins/workflow/src/__tests__/instructions/destroy.test.ts
@@ -21,7 +21,7 @@ describe('workflow > instructions > destroy', () => {
workflow = await WorkflowModel.create({
title: 'test workflow',
enabled: true,
- type: 'model',
+ type: 'collection',
config: {
mode: 1,
collection: 'posts'
diff --git a/packages/plugins/workflow/src/__tests__/instructions/query.test.ts b/packages/plugins/workflow/src/__tests__/instructions/query.test.ts
index a9a3c7110..c55bfa579 100644
--- a/packages/plugins/workflow/src/__tests__/instructions/query.test.ts
+++ b/packages/plugins/workflow/src/__tests__/instructions/query.test.ts
@@ -21,7 +21,7 @@ describe('workflow > instructions > query', () => {
workflow = await WorkflowModel.create({
title: 'test workflow',
enabled: true,
- type: 'model',
+ type: 'collection',
config: {
mode: 1,
collection: 'posts'
diff --git a/packages/plugins/workflow/src/__tests__/instructions/update.test.ts b/packages/plugins/workflow/src/__tests__/instructions/update.test.ts
index 9c8dacb5d..d70cb06a9 100644
--- a/packages/plugins/workflow/src/__tests__/instructions/update.test.ts
+++ b/packages/plugins/workflow/src/__tests__/instructions/update.test.ts
@@ -21,7 +21,7 @@ describe('workflow > instructions > update', () => {
workflow = await WorkflowModel.create({
title: 'test workflow',
enabled: true,
- type: 'model',
+ type: 'collection',
config: {
mode: 1,
collection: 'posts'
diff --git a/packages/plugins/workflow/src/triggers/model.ts b/packages/plugins/workflow/src/triggers/collection.ts
similarity index 92%
rename from packages/plugins/workflow/src/triggers/model.ts
rename to packages/plugins/workflow/src/triggers/collection.ts
index ff1bb0d49..866f62fae 100644
--- a/packages/plugins/workflow/src/triggers/model.ts
+++ b/packages/plugins/workflow/src/triggers/collection.ts
@@ -37,7 +37,7 @@ function bindHandler(this: WorkflowModel, callback: Function) {
}
export default {
- name: 'model',
+ name: 'collection',
on(this: WorkflowModel, callback: Function) {
const { database } = this.constructor;
const { collection, mode } = this.config;
@@ -47,7 +47,9 @@ export default {
}
// TODO: duplication when mode change should be considered
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));
}
}
diff --git a/packages/plugins/workflow/src/triggers/index.ts b/packages/plugins/workflow/src/triggers/index.ts
index ca26d4bd2..4d574bf9a 100644
--- a/packages/plugins/workflow/src/triggers/index.ts
+++ b/packages/plugins/workflow/src/triggers/index.ts
@@ -1,6 +1,6 @@
import { Registry } from '@nocobase/utils';
import WorkflowModel from '../models/Workflow';
-import modelTrigger from './model';
+import collectionlTrigger from './collection';
export interface Trigger {
name: string;
@@ -12,4 +12,4 @@ export const triggers = new Registry();
export default triggers;
-triggers.register(modelTrigger.name, modelTrigger);
+triggers.register(collectionlTrigger.name, collectionlTrigger);