mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 07:38:13 +00:00
feat(plugin-workflow): branch presetting (#5570)
* fix(client): fix core component bug and warnings * feat(plugin-workflow): add preset and branching config before add node * refactor(plugin-workflow): fix AddNodeContext and adjust styles * fix(plugin-workflow): fix default config value in preset form * fix(plugin-workflow): fix e2e cases * fix(plugin-workflow-parallel): fix e2e test cases * fix(plugin-workflow): fix e2e test cases
This commit is contained in:
parent
c728146160
commit
a223f4448e
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import { css } from '@emotion/css';
|
||||
import { observer, RecursionField, useField, useFieldSchema, useForm } from '@formily/react';
|
||||
import { observer, RecursionField, useField, useFieldSchema } from '@formily/react';
|
||||
import { Modal, ModalProps } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import React, { useMemo } from 'react';
|
||||
@ -43,7 +43,6 @@ export const InternalActionModal: React.FC<ActionDrawerProps<ModalProps>> = obse
|
||||
const { visible, setVisible, openSize = 'middle', modalProps } = useActionContext();
|
||||
const actualWidth = width ?? openSizeWidthMap.get(openSize);
|
||||
const schema = useFieldSchema();
|
||||
const form = useForm();
|
||||
const field = useField();
|
||||
const { token } = useToken();
|
||||
const tabContext = useTabsContext();
|
||||
@ -91,7 +90,6 @@ export const InternalActionModal: React.FC<ActionDrawerProps<ModalProps>> = obse
|
||||
open={visible}
|
||||
onCancel={() => {
|
||||
setVisible(false, true);
|
||||
form.reset();
|
||||
}}
|
||||
className={classNames(
|
||||
others.className,
|
||||
|
@ -45,7 +45,7 @@ const useIsSubPageClosedByPageMenu = () => {
|
||||
|
||||
export const ActionContextProvider: React.FC<ActionContextProps & { value?: ActionContextProps }> = (props) => {
|
||||
const [submitted, setSubmitted] = useState(false); //是否有提交记录
|
||||
const { visible } = { ...props, ...props.value } || {};
|
||||
const { visible } = { ...props, ...props.value };
|
||||
const { setSubmitted: setParentSubmitted } = { ...props, ...props.value };
|
||||
const service = useBlockServiceInActionButton();
|
||||
const isSubPageClosedByPageMenu = useIsSubPageClosedByPageMenu();
|
||||
|
@ -244,11 +244,12 @@ const SortableRow = (props: {
|
||||
const { setNodeRef, isOver, active, over } = useSortable({
|
||||
id,
|
||||
});
|
||||
const { rowIndex, ...others } = props;
|
||||
|
||||
const { ref, inView } = useInView({
|
||||
threshold: 0,
|
||||
triggerOnce: true,
|
||||
initialInView: !!process.env.__E2E__ || isInSubTable || (props.rowIndex || 0) < INITIAL_ROWS_NUMBER,
|
||||
initialInView: !!process.env.__E2E__ || isInSubTable || (rowIndex || 0) < INITIAL_ROWS_NUMBER,
|
||||
skip: !!process.env.__E2E__ || isInSubTable,
|
||||
});
|
||||
|
||||
@ -282,7 +283,7 @@ const SortableRow = (props: {
|
||||
}
|
||||
ref(node);
|
||||
}}
|
||||
{...props}
|
||||
{...others}
|
||||
className={classNames(props.className, { [className]: active && isOver })}
|
||||
/>
|
||||
</InViewContext.Provider>
|
||||
|
@ -355,6 +355,7 @@ export default class extends Instruction {
|
||||
default: 0,
|
||||
},
|
||||
};
|
||||
branching = true;
|
||||
scope = {
|
||||
renderEngineReference,
|
||||
};
|
||||
|
@ -58,6 +58,7 @@ export default class extends Instruction {
|
||||
default: 'all',
|
||||
},
|
||||
};
|
||||
branching = true;
|
||||
components = {
|
||||
RadioWithTooltip,
|
||||
};
|
||||
@ -118,6 +119,7 @@ export default class extends Instruction {
|
||||
icon={<PlusOutlined />}
|
||||
onClick={() => setBranchCount(branchCount - 1)}
|
||||
disabled={workflow.executed}
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
) : null
|
||||
@ -145,6 +147,7 @@ export default class extends Instruction {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
`}
|
||||
size="small"
|
||||
onClick={() => setBranchCount(branchCount + 1)}
|
||||
disabled={workflow.executed}
|
||||
/>
|
||||
|
@ -75,8 +75,9 @@ test.describe('All succeeded', () => {
|
||||
await parallelBranchNode.addBranchButton.click();
|
||||
// 分支1添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-1`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const oneConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(oneConditionNodeName);
|
||||
const oneConditionNode = new ConditionYesNode(page, oneConditionNodeName);
|
||||
@ -87,8 +88,9 @@ test.describe('All succeeded', () => {
|
||||
await oneConditionNode.submitButton.click();
|
||||
// 分支2添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-2`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const twoConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(twoConditionNodeName);
|
||||
const twoConditionNode = new ConditionYesNode(page, twoConditionNodeName);
|
||||
@ -99,8 +101,9 @@ test.describe('All succeeded', () => {
|
||||
await twoConditionNode.submitButton.click();
|
||||
// 分支3添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-3`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const threeConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(threeConditionNodeName);
|
||||
const threeConditionNode = new ConditionYesNode(page, threeConditionNodeName);
|
||||
@ -210,8 +213,9 @@ test.describe('All succeeded', () => {
|
||||
await parallelBranchNode.addBranchButton.click();
|
||||
// 分支1添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-1`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const oneConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(oneConditionNodeName);
|
||||
const oneConditionNode = new ConditionYesNode(page, oneConditionNodeName);
|
||||
@ -222,8 +226,9 @@ test.describe('All succeeded', () => {
|
||||
await oneConditionNode.submitButton.click();
|
||||
// 分支2添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-2`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const twoConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(twoConditionNodeName);
|
||||
const twoConditionNode = new ConditionYesNode(page, twoConditionNodeName);
|
||||
@ -234,8 +239,9 @@ test.describe('All succeeded', () => {
|
||||
await twoConditionNode.submitButton.click();
|
||||
// 分支3添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-3`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const threeConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(threeConditionNodeName);
|
||||
const threeConditionNode = new ConditionYesNode(page, threeConditionNodeName);
|
||||
@ -344,8 +350,9 @@ test.describe('All succeeded', () => {
|
||||
await parallelBranchNode.addBranchButton.click();
|
||||
// 分支1添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-1`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const oneConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(oneConditionNodeName);
|
||||
const oneConditionNode = new ConditionYesNode(page, oneConditionNodeName);
|
||||
@ -356,8 +363,9 @@ test.describe('All succeeded', () => {
|
||||
await oneConditionNode.submitButton.click();
|
||||
// 分支2添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-2`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const twoConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(twoConditionNodeName);
|
||||
const twoConditionNode = new ConditionYesNode(page, twoConditionNodeName);
|
||||
@ -368,8 +376,9 @@ test.describe('All succeeded', () => {
|
||||
await twoConditionNode.submitButton.click();
|
||||
// 分支3添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-3`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const threeConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(threeConditionNodeName);
|
||||
const threeConditionNode = new ConditionYesNode(page, threeConditionNodeName);
|
||||
@ -477,8 +486,9 @@ test.describe('All succeeded', () => {
|
||||
await parallelBranchNode.addBranchButton.click();
|
||||
// 分支1添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-1`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const oneConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(oneConditionNodeName);
|
||||
const oneConditionNode = new ConditionYesNode(page, oneConditionNodeName);
|
||||
@ -489,8 +499,9 @@ test.describe('All succeeded', () => {
|
||||
await oneConditionNode.submitButton.click();
|
||||
// 分支2添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-2`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const twoConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(twoConditionNodeName);
|
||||
const twoConditionNode = new ConditionYesNode(page, twoConditionNodeName);
|
||||
@ -501,8 +512,9 @@ test.describe('All succeeded', () => {
|
||||
await twoConditionNode.submitButton.click();
|
||||
// 分支3添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-3`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const threeConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(threeConditionNodeName);
|
||||
const threeConditionNode = new ConditionYesNode(page, threeConditionNodeName);
|
||||
|
@ -78,8 +78,9 @@ test.describe('Any succeeded', () => {
|
||||
await parallelBranchNode.addBranchButton.click();
|
||||
// 分支1添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-1`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const oneConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(oneConditionNodeName);
|
||||
const oneConditionNode = new ConditionYesNode(page, oneConditionNodeName);
|
||||
@ -90,8 +91,9 @@ test.describe('Any succeeded', () => {
|
||||
await oneConditionNode.submitButton.click();
|
||||
// 分支2添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-2`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const twoConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(twoConditionNodeName);
|
||||
const twoConditionNode = new ConditionYesNode(page, twoConditionNodeName);
|
||||
@ -102,8 +104,9 @@ test.describe('Any succeeded', () => {
|
||||
await twoConditionNode.submitButton.click();
|
||||
// 分支3添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-3`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const threeConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(threeConditionNodeName);
|
||||
const threeConditionNode = new ConditionYesNode(page, threeConditionNodeName);
|
||||
@ -214,8 +217,9 @@ test.describe('Any succeeded', () => {
|
||||
await parallelBranchNode.addBranchButton.click();
|
||||
// 分支1添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-1`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const oneConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(oneConditionNodeName);
|
||||
const oneConditionNode = new ConditionYesNode(page, oneConditionNodeName);
|
||||
@ -226,8 +230,9 @@ test.describe('Any succeeded', () => {
|
||||
await oneConditionNode.submitButton.click();
|
||||
// 分支2添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-2`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const twoConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(twoConditionNodeName);
|
||||
const twoConditionNode = new ConditionYesNode(page, twoConditionNodeName);
|
||||
@ -238,8 +243,9 @@ test.describe('Any succeeded', () => {
|
||||
await twoConditionNode.submitButton.click();
|
||||
// 分支3添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-3`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const threeConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(threeConditionNodeName);
|
||||
const threeConditionNode = new ConditionYesNode(page, threeConditionNodeName);
|
||||
@ -351,8 +357,9 @@ test.describe('Any succeeded', () => {
|
||||
await parallelBranchNode.addBranchButton.click();
|
||||
// 分支1添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-1`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const oneConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(oneConditionNodeName);
|
||||
const oneConditionNode = new ConditionYesNode(page, oneConditionNodeName);
|
||||
@ -363,8 +370,9 @@ test.describe('Any succeeded', () => {
|
||||
await oneConditionNode.submitButton.click();
|
||||
// 分支2添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-2`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const twoConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(twoConditionNodeName);
|
||||
const twoConditionNode = new ConditionYesNode(page, twoConditionNodeName);
|
||||
@ -375,8 +383,9 @@ test.describe('Any succeeded', () => {
|
||||
await twoConditionNode.submitButton.click();
|
||||
// 分支3添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-3`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const threeConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(threeConditionNodeName);
|
||||
const threeConditionNode = new ConditionYesNode(page, threeConditionNodeName);
|
||||
|
@ -77,8 +77,9 @@ test.describe('Any succeeded or failed', () => {
|
||||
await parallelBranchNode.submitButton.click();
|
||||
// 分支1添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-1`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const oneConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(oneConditionNodeName);
|
||||
const oneConditionNode = new ConditionYesNode(page, oneConditionNodeName);
|
||||
@ -89,8 +90,9 @@ test.describe('Any succeeded or failed', () => {
|
||||
await oneConditionNode.submitButton.click();
|
||||
// 分支2添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-2`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const twoConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(twoConditionNodeName);
|
||||
const twoConditionNode = new ConditionYesNode(page, twoConditionNodeName);
|
||||
@ -198,8 +200,9 @@ test.describe('Any succeeded or failed', () => {
|
||||
await parallelBranchNode.submitButton.click();
|
||||
// 分支1添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-1`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const oneConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(oneConditionNodeName);
|
||||
const oneConditionNode = new ConditionYesNode(page, oneConditionNodeName);
|
||||
@ -210,8 +213,9 @@ test.describe('Any succeeded or failed', () => {
|
||||
await oneConditionNode.submitButton.click();
|
||||
// 分支2添加判断节点
|
||||
await page.getByLabel(`add-button-parallel-${parallelBranchNodeTitle}-2`).click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Continue when "Yes"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const twoConditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(twoConditionNodeName);
|
||||
const twoConditionNode = new ConditionYesNode(page, twoConditionNodeName);
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"Parallel branch": "分支",
|
||||
"Parallel branch": "并行分支",
|
||||
"Run multiple branch processes in parallel.": "并行运行多个分支流程。",
|
||||
"Add branch": "增加分支",
|
||||
"Mode": "执行模式",
|
||||
|
@ -1,143 +0,0 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { Button, Dropdown, MenuProps } from 'antd';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
|
||||
import { css, useAPIClient, useCompile, usePlugin } from '@nocobase/client';
|
||||
|
||||
import WorkflowPlugin from '.';
|
||||
import { useFlowContext } from './FlowContext';
|
||||
import { NAMESPACE } from './locale';
|
||||
import { Instruction } from './nodes';
|
||||
import useStyles from './style';
|
||||
|
||||
interface AddButtonProps {
|
||||
upstream;
|
||||
branchIndex?: number | null;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export function AddButton(props: AddButtonProps) {
|
||||
const { upstream, branchIndex = null } = props;
|
||||
const engine = usePlugin(WorkflowPlugin);
|
||||
const compile = useCompile();
|
||||
const api = useAPIClient();
|
||||
const { workflow, refresh } = useFlowContext() ?? {};
|
||||
const instructionList = Array.from(engine.instructions.getValues()) as Instruction[];
|
||||
const { styles } = useStyles();
|
||||
const [creating, setCreating] = useState(false);
|
||||
|
||||
const groups = useMemo(() => {
|
||||
return [
|
||||
{ key: 'control', label: `{{t("Control", { ns: "${NAMESPACE}" })}}` },
|
||||
{ key: 'calculation', label: `{{t("Calculation", { ns: "${NAMESPACE}" })}}` },
|
||||
{ key: 'collection', label: `{{t("Collection operations", { ns: "${NAMESPACE}" })}}` },
|
||||
{ key: 'manual', label: `{{t("Manual", { ns: "${NAMESPACE}" })}}` },
|
||||
{ key: 'extended', label: `{{t("Extended types", { ns: "${NAMESPACE}" })}}` },
|
||||
]
|
||||
.map((group) => {
|
||||
const groupInstructions = instructionList.filter(
|
||||
(item) =>
|
||||
item.group === group.key &&
|
||||
(item.isAvailable ? item.isAvailable({ engine, workflow, upstream, branchIndex }) : true),
|
||||
);
|
||||
|
||||
return {
|
||||
...group,
|
||||
type: 'group',
|
||||
children: groupInstructions.map((item) => ({
|
||||
role: 'button',
|
||||
'aria-label': item.type,
|
||||
key: item.type,
|
||||
label: item.title,
|
||||
type: item.options ? 'subMenu' : null,
|
||||
children: item.options
|
||||
? item.options.map((option) => ({
|
||||
role: 'button',
|
||||
'aria-label': option.key,
|
||||
key: option.key,
|
||||
label: option.label,
|
||||
}))
|
||||
: null,
|
||||
})),
|
||||
};
|
||||
})
|
||||
.filter((group) => group.children.length);
|
||||
}, [branchIndex, engine, instructionList, upstream, workflow]);
|
||||
|
||||
const onCreate = useCallback(
|
||||
async ({ keyPath }) => {
|
||||
const type = keyPath.pop();
|
||||
const [optionKey] = keyPath;
|
||||
const instruction = engine.instructions.get(type);
|
||||
const config = instruction.createDefaultConfig();
|
||||
if (optionKey) {
|
||||
const { value } = instruction.options?.find((item) => item.key === optionKey) ?? {};
|
||||
Object.assign(config, typeof value === 'function' ? value() : value);
|
||||
}
|
||||
|
||||
if (workflow) {
|
||||
setCreating(true);
|
||||
try {
|
||||
await api.resource('workflows.nodes', workflow.id).create({
|
||||
values: {
|
||||
type,
|
||||
upstreamId: upstream?.id ?? null,
|
||||
branchIndex,
|
||||
title: compile(instruction.title),
|
||||
config,
|
||||
},
|
||||
});
|
||||
refresh();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} finally {
|
||||
setCreating(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
[api, branchIndex, engine.instructions, refresh, upstream?.id, workflow],
|
||||
);
|
||||
|
||||
const menu = useMemo<MenuProps>(() => {
|
||||
return {
|
||||
onClick: onCreate,
|
||||
items: compile(groups),
|
||||
};
|
||||
}, [groups, onCreate]);
|
||||
|
||||
if (!workflow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.addButtonClass}>
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
menu={menu}
|
||||
disabled={workflow.executed}
|
||||
overlayClassName={css`
|
||||
.ant-dropdown-menu-root {
|
||||
max-height: 30em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Button
|
||||
aria-label={props['aria-label'] || 'add-button'}
|
||||
shape="circle"
|
||||
icon={<PlusOutlined />}
|
||||
loading={creating}
|
||||
/>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,412 @@
|
||||
/**
|
||||
* This file is part of the NocoBase (R) project.
|
||||
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
||||
* Authors: NocoBase Team.
|
||||
*
|
||||
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
||||
import { createForm } from '@formily/core';
|
||||
import { observer, useForm } from '@formily/react';
|
||||
|
||||
import {
|
||||
ActionContextProvider,
|
||||
css,
|
||||
SchemaComponent,
|
||||
useActionContext,
|
||||
useAPIClient,
|
||||
useCancelAction,
|
||||
useCompile,
|
||||
usePlugin,
|
||||
} from '@nocobase/client';
|
||||
|
||||
import WorkflowPlugin, { Instruction, useStyles } from '.';
|
||||
import { useFlowContext } from './FlowContext';
|
||||
import { lang, NAMESPACE } from './locale';
|
||||
import { RadioWithTooltip } from './components';
|
||||
import { uid } from '@nocobase/utils/client';
|
||||
import { Button, Dropdown } from 'antd';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
|
||||
interface AddButtonProps {
|
||||
upstream;
|
||||
branchIndex?: number | null;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export function AddButton(props: AddButtonProps) {
|
||||
const { upstream, branchIndex = null } = props;
|
||||
const engine = usePlugin(WorkflowPlugin);
|
||||
const compile = useCompile();
|
||||
const { workflow } = useFlowContext() ?? {};
|
||||
const instructionList = Array.from(engine.instructions.getValues()) as Instruction[];
|
||||
const { styles } = useStyles();
|
||||
const { onCreate, creating } = useAddNodeContext();
|
||||
|
||||
const groups = useMemo(() => {
|
||||
const result = [
|
||||
{ key: 'control', label: `{{t("Control", { ns: "${NAMESPACE}" })}}` },
|
||||
{ key: 'calculation', label: `{{t("Calculation", { ns: "${NAMESPACE}" })}}` },
|
||||
{ key: 'collection', label: `{{t("Collection operations", { ns: "${NAMESPACE}" })}}` },
|
||||
{ key: 'manual', label: `{{t("Manual", { ns: "${NAMESPACE}" })}}` },
|
||||
{ key: 'extended', label: `{{t("Extended types", { ns: "${NAMESPACE}" })}}` },
|
||||
]
|
||||
.map((group) => {
|
||||
const groupInstructions = instructionList.filter(
|
||||
(item) =>
|
||||
item.group === group.key &&
|
||||
(item.isAvailable ? item.isAvailable({ engine, workflow, upstream, branchIndex }) : true),
|
||||
);
|
||||
|
||||
return {
|
||||
...group,
|
||||
type: 'group',
|
||||
children: groupInstructions.map((item) => ({
|
||||
role: 'button',
|
||||
'aria-label': item.type,
|
||||
key: item.type,
|
||||
label: item.title,
|
||||
})),
|
||||
};
|
||||
})
|
||||
.filter((group) => group.children.length);
|
||||
|
||||
return compile(result);
|
||||
}, [branchIndex, compile, engine, instructionList, upstream, workflow]);
|
||||
|
||||
const onClick = useCallback(
|
||||
async ({ keyPath }) => {
|
||||
const [type] = keyPath;
|
||||
onCreate({ type, upstream, branchIndex });
|
||||
},
|
||||
[branchIndex, onCreate, upstream],
|
||||
);
|
||||
|
||||
if (!workflow) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.addButtonClass}>
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: groups,
|
||||
onClick,
|
||||
}}
|
||||
disabled={workflow.executed}
|
||||
overlayClassName={css`
|
||||
.ant-dropdown-menu-root {
|
||||
max-height: 30em;
|
||||
overflow-y: auto;
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Button
|
||||
aria-label={props['aria-label'] || 'add-button'}
|
||||
shape="circle"
|
||||
icon={<PlusOutlined />}
|
||||
loading={creating?.upstreamId == upstream?.id && creating?.branchIndex === branchIndex}
|
||||
size="small"
|
||||
/>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function useAddNodeSubmitAction() {
|
||||
const form = useForm();
|
||||
const api = useAPIClient();
|
||||
const { workflow, refresh } = useFlowContext();
|
||||
const { presetting, setPresetting, setCreating } = useAddNodeContext();
|
||||
const ctx = useActionContext();
|
||||
return {
|
||||
async run() {
|
||||
if (!presetting) {
|
||||
return;
|
||||
}
|
||||
await form.submit();
|
||||
setCreating(presetting.data);
|
||||
try {
|
||||
const {
|
||||
data: { data: newNode },
|
||||
} = await api.resource('workflows.nodes', workflow.id).create({
|
||||
values: {
|
||||
...presetting.data,
|
||||
config: {
|
||||
...presetting.data.config,
|
||||
...form.values.config,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (form.values.downstreamBranchIndex !== false && newNode.downstreamId) {
|
||||
await api.resource('flow_nodes').update({
|
||||
filterByTk: newNode.downstreamId,
|
||||
values: {
|
||||
branchIndex: form.values.downstreamBranchIndex,
|
||||
upstream: {
|
||||
id: newNode.id,
|
||||
downstreamId: null,
|
||||
},
|
||||
},
|
||||
updateAssociationValues: ['upstream'],
|
||||
});
|
||||
}
|
||||
ctx.setVisible(false);
|
||||
setPresetting(null);
|
||||
refresh();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} finally {
|
||||
setCreating(null);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const AddNodeContext = createContext(null);
|
||||
|
||||
export function useAddNodeContext() {
|
||||
return useContext(AddNodeContext);
|
||||
}
|
||||
|
||||
const defaultBranchingOptions = [
|
||||
{
|
||||
label: `{{t('After end of branches', { ns: "${NAMESPACE}" })}}`,
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
label: `{{t('Inside of branch', { ns: "${NAMESPACE}" })}}`,
|
||||
value: 0,
|
||||
},
|
||||
];
|
||||
|
||||
const DownstreamBranchIndex = observer((props) => {
|
||||
const { presetting } = useAddNodeContext();
|
||||
const { nodes } = useFlowContext();
|
||||
const { values } = useForm();
|
||||
const options = useMemo(() => {
|
||||
if (!presetting?.instruction) {
|
||||
return [];
|
||||
}
|
||||
const { instruction, data } = presetting;
|
||||
const downstream = data.upstreamId
|
||||
? nodes.find((item) => item.upstreamId === data.upstreamId && item.branchIndex === data.branchIndex)
|
||||
: nodes.find((item) => item.upstreamId === null);
|
||||
if (!downstream) {
|
||||
return [];
|
||||
}
|
||||
const branching =
|
||||
typeof instruction.branching === 'function' ? instruction.branching(values.config ?? {}) : instruction.branching;
|
||||
if (!branching) {
|
||||
return [];
|
||||
}
|
||||
return branching === true ? defaultBranchingOptions : branching;
|
||||
}, [presetting, nodes, values.config]);
|
||||
|
||||
if (!options.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { data } = presetting;
|
||||
|
||||
return (
|
||||
<SchemaComponent
|
||||
components={{
|
||||
RadioWithTooltip,
|
||||
}}
|
||||
schema={{
|
||||
name: `${data.type ?? 'unknown'}-${data.upstreamId ?? 'root'}-${data.branchIndex}`,
|
||||
type: 'void',
|
||||
properties: {
|
||||
downstreamBranchIndex: {
|
||||
type: 'number',
|
||||
title: lang('Move all downstream nodes to', { ns: NAMESPACE }),
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'RadioWithTooltip',
|
||||
'x-component-props': {
|
||||
options,
|
||||
direction: 'vertical',
|
||||
},
|
||||
default: false,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
// return (
|
||||
// <FormItem label={lang('Move all downstream nodes to', { ns: NAMESPACE })}>
|
||||
// <RadioWithTooltip {...props} options={options} defaultValue={-1} direction="vertical" />
|
||||
// </FormItem>
|
||||
// );
|
||||
});
|
||||
|
||||
function PresetFieldset() {
|
||||
const { presetting } = useAddNodeContext();
|
||||
if (!presetting?.instruction.presetFieldset) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<SchemaComponent
|
||||
schema={{
|
||||
type: 'void',
|
||||
properties: {
|
||||
config: {
|
||||
type: 'object',
|
||||
properties: presetting.instruction.presetFieldset,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function AddNodeContextProvider(props) {
|
||||
const api = useAPIClient();
|
||||
const compile = useCompile();
|
||||
const engine = usePlugin(WorkflowPlugin);
|
||||
const [creating, setCreating] = useState(null);
|
||||
const [presetting, setPresetting] = useState(null);
|
||||
const [formValueChanged, setFormValueChanged] = useState(false);
|
||||
const { workflow, nodes, refresh } = useFlowContext() ?? {};
|
||||
|
||||
const form = useMemo(() => createForm(), []);
|
||||
|
||||
const onModalCancel = useCallback(
|
||||
(visible) => {
|
||||
if (!visible) {
|
||||
form.reset();
|
||||
form.clearFormGraph('*');
|
||||
setPresetting(null);
|
||||
}
|
||||
},
|
||||
[form],
|
||||
);
|
||||
|
||||
const create = useCallback(
|
||||
async (data) => {
|
||||
setCreating(data);
|
||||
try {
|
||||
await api.resource('workflows.nodes', workflow.id).create({
|
||||
values: data,
|
||||
});
|
||||
refresh();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} finally {
|
||||
setCreating(null);
|
||||
}
|
||||
},
|
||||
[api, refresh, workflow.id],
|
||||
);
|
||||
|
||||
const onCreate = useCallback(
|
||||
({ type, upstream, branchIndex }) => {
|
||||
const instruction = engine.instructions.get(type);
|
||||
if (!instruction) {
|
||||
console.error(`Instruction "${type}" not found`);
|
||||
return;
|
||||
}
|
||||
const data = {
|
||||
key: uid(),
|
||||
type,
|
||||
upstreamId: upstream?.id ?? null,
|
||||
branchIndex,
|
||||
title: compile(instruction.title),
|
||||
config: instruction.createDefaultConfig?.() ?? {},
|
||||
};
|
||||
const downstream = upstream?.id
|
||||
? nodes.find((item) => item.upstreamId === data.upstreamId && item.branchIndex === data.branchIndex)
|
||||
: nodes.find((item) => item.upstreamId === null);
|
||||
if (
|
||||
instruction.presetFieldset ||
|
||||
((typeof instruction.branching === 'function' ? instruction.branching(data.config) : instruction.branching) &&
|
||||
downstream)
|
||||
) {
|
||||
setPresetting({ data, instruction });
|
||||
return;
|
||||
}
|
||||
|
||||
create(data);
|
||||
},
|
||||
[compile, create, engine.instructions],
|
||||
);
|
||||
|
||||
return (
|
||||
<AddNodeContext.Provider value={{ presetting, setPresetting, onCreate, creating, setCreating }}>
|
||||
{props.children}
|
||||
<ActionContextProvider
|
||||
value={{
|
||||
visible: Boolean(presetting),
|
||||
setVisible: onModalCancel,
|
||||
formValueChanged,
|
||||
setFormValueChanged,
|
||||
openSize: 'small',
|
||||
}}
|
||||
>
|
||||
<SchemaComponent
|
||||
components={{
|
||||
DownstreamBranchIndex,
|
||||
PresetFieldset,
|
||||
}}
|
||||
scope={{
|
||||
useCancelAction,
|
||||
useAddNodeSubmitAction,
|
||||
}}
|
||||
schema={{
|
||||
name: `modal`,
|
||||
type: 'void',
|
||||
'x-decorator': 'FormV2',
|
||||
'x-decorator-props': {
|
||||
form,
|
||||
},
|
||||
'x-component': 'Action.Modal',
|
||||
title: `{{ t("Add node", { ns: "${NAMESPACE}" }) }}`,
|
||||
properties: {
|
||||
config: {
|
||||
type: 'void',
|
||||
'x-component': 'PresetFieldset',
|
||||
},
|
||||
downstreamBranchIndex: {
|
||||
type: 'void',
|
||||
'x-component': 'DownstreamBranchIndex',
|
||||
},
|
||||
footer: {
|
||||
'x-component': 'Action.Modal.Footer',
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-component': 'ActionBar',
|
||||
properties: {
|
||||
cancel: {
|
||||
type: 'void',
|
||||
title: '{{ t("Cancel") }}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ useCancelAction }}',
|
||||
},
|
||||
},
|
||||
submit: {
|
||||
type: 'void',
|
||||
title: `{{ t("Submit") }}`,
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
htmlType: 'submit',
|
||||
useAction: '{{ useAddNodeSubmitAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</ActionContextProvider>
|
||||
</AddNodeContext.Provider>
|
||||
);
|
||||
}
|
@ -12,7 +12,7 @@ import { CloseOutlined } from '@ant-design/icons';
|
||||
|
||||
import { css, cx } from '@nocobase/client';
|
||||
|
||||
import { AddButton } from './AddButton';
|
||||
import { AddButton } from './AddNodeContext';
|
||||
import { useGetAriaLabelOfAddButton } from './hooks/useGetAriaLabelOfAddButton';
|
||||
import { Node } from './nodes';
|
||||
import useStyles from './style';
|
||||
|
@ -18,6 +18,7 @@ import { useFlowContext } from './FlowContext';
|
||||
import { lang } from './locale';
|
||||
import useStyles from './style';
|
||||
import { TriggerConfig } from './triggers';
|
||||
import { AddNodeContextProvider } from './AddNodeContext';
|
||||
|
||||
export function CanvasContent({ entry }) {
|
||||
const { styles } = useStyles();
|
||||
@ -27,41 +28,43 @@ export function CanvasContent({ entry }) {
|
||||
return (
|
||||
<div className="workflow-canvas-wrapper">
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback} onError={console.error}>
|
||||
<div className="workflow-canvas" style={{ zoom: zoom / 100 }}>
|
||||
<div
|
||||
className={cx(
|
||||
styles.branchBlockClass,
|
||||
css`
|
||||
margin-top: 0 !important;
|
||||
`,
|
||||
)}
|
||||
>
|
||||
<div className={styles.branchClass}>
|
||||
{workflow?.executed ? (
|
||||
<Alert
|
||||
type="warning"
|
||||
message={lang('Executed workflow cannot be modified. Could be copied to a new version to modify.')}
|
||||
showIcon
|
||||
className={css`
|
||||
margin-bottom: 1em;
|
||||
`}
|
||||
/>
|
||||
) : null}
|
||||
<TriggerConfig />
|
||||
<div
|
||||
className={cx(
|
||||
styles.branchBlockClass,
|
||||
css`
|
||||
margin-top: 0 !important;
|
||||
`,
|
||||
)}
|
||||
>
|
||||
<Branch entry={entry} />
|
||||
<AddNodeContextProvider>
|
||||
<div className="workflow-canvas" style={{ zoom: zoom / 100 }}>
|
||||
<div
|
||||
className={cx(
|
||||
styles.branchBlockClass,
|
||||
css`
|
||||
margin-top: 0 !important;
|
||||
`,
|
||||
)}
|
||||
>
|
||||
<div className={styles.branchClass}>
|
||||
{workflow?.executed ? (
|
||||
<Alert
|
||||
type="warning"
|
||||
message={lang('Executed workflow cannot be modified. Could be copied to a new version to modify.')}
|
||||
showIcon
|
||||
className={css`
|
||||
margin-bottom: 1em;
|
||||
`}
|
||||
/>
|
||||
) : null}
|
||||
<TriggerConfig />
|
||||
<div
|
||||
className={cx(
|
||||
styles.branchBlockClass,
|
||||
css`
|
||||
margin-top: 0 !important;
|
||||
`,
|
||||
)}
|
||||
>
|
||||
<Branch entry={entry} />
|
||||
</div>
|
||||
<div className={styles.terminalClass}>{lang('End')}</div>
|
||||
</div>
|
||||
<div className={styles.terminalClass}>{lang('End')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AddNodeContextProvider>
|
||||
</ErrorBoundary>
|
||||
<div className="workflow-canvas-zoomer">
|
||||
<Slider vertical reverse defaultValue={100} step={10} min={10} value={zoom} onChange={setZoom} />
|
||||
|
@ -91,8 +91,9 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -239,8 +240,9 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -383,8 +385,9 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -529,8 +532,9 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
|
@ -65,8 +65,9 @@ test('Collection event add data trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -178,8 +179,9 @@ test('Collection event add data trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -291,8 +293,9 @@ test('Collection event Add Data Trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -406,8 +409,9 @@ test('Collection event add data trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
|
@ -68,8 +68,9 @@ test('Collection event Add Data Trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -195,8 +196,9 @@ test('Collection event Add Data Trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -319,8 +321,9 @@ test('Collection event Add Data Trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -446,8 +449,9 @@ test('Collection event Add Data Trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -594,8 +598,9 @@ test('Collection event add data trigger, determine the trigger node integer vari
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -752,8 +757,9 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -900,8 +906,9 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -1051,8 +1058,9 @@ test('Collection event add data trigger, determine the trigger node integer vari
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
|
@ -65,8 +65,9 @@ test('Collection event add data trigger, determine trigger node integer field va
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -189,8 +190,9 @@ test('Collection event Add Data Trigger, determines that the trigger node intege
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -310,8 +312,9 @@ test('Collection event Add Data Trigger, determines that the trigger node intege
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
@ -431,8 +434,9 @@ test('Collection event add data trigger, determines that the trigger node intege
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByText('Branch into "Yes" and "No"').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
|
@ -69,8 +69,8 @@ test('Collection event add data trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -152,8 +152,8 @@ test('Collection event add data trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -236,8 +236,8 @@ test('Collection event Add Data Trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -322,8 +322,8 @@ test('Collection event add data trigger, determines that the trigger node single
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -432,8 +432,8 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -546,8 +546,8 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -657,8 +657,8 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -773,8 +773,8 @@ test('Collection event add data trigger, determine trigger node integer variable
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
|
@ -67,8 +67,8 @@ test('Collection event Add Data Trigger, Formula engine, determines that the tri
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -157,8 +157,8 @@ test('Collection event Add Data Trigger, Formula engine, determines that the tri
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -248,8 +248,8 @@ test('Collection event Add Data Trigger, Formula engine, determines that the tri
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -337,8 +337,8 @@ test('Collection event Add Data Trigger, Formula engine, determines that the tri
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -452,8 +452,8 @@ test('Collection event add data trigger, Formula engine, determine the trigger n
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -570,8 +570,8 @@ test('Collection event add data trigger, Formula engine, determine trigger node
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -686,8 +686,8 @@ test('Collection event add data trigger, Formula engine, determine trigger node
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -804,8 +804,8 @@ test('Collection event add data trigger, Formula engine, determine the trigger n
|
||||
await page.waitForLoadState('load');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
|
@ -64,8 +64,8 @@ test('Collection event add data trigger, Math engine, determine trigger node int
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -155,8 +155,8 @@ test('Collection event Add Data Trigger, Math engine, determines that the trigge
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -246,8 +246,8 @@ test('Collection event Add Data Trigger, Math engine, determines that the trigge
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
@ -336,8 +336,8 @@ test('Collection event add data trigger, Math engine, determines that the trigge
|
||||
await page.waitForLoadState('load');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
|
@ -20,6 +20,12 @@ import useStyles from '../style';
|
||||
import { useWorkflowVariableOptions, WorkflowVariableTextArea } from '../variable';
|
||||
import { CalculationConfig } from '../components/Calculation';
|
||||
|
||||
const BRANCH_INDEX = {
|
||||
DEFAULT: null,
|
||||
ON_TRUE: 1,
|
||||
ON_FALSE: 0,
|
||||
} as const;
|
||||
|
||||
export default class extends Instruction {
|
||||
title = `{{t("Condition", { ns: "${NAMESPACE}" })}}`;
|
||||
type = 'condition';
|
||||
@ -107,18 +113,44 @@ export default class extends Instruction {
|
||||
required: true,
|
||||
},
|
||||
};
|
||||
options = [
|
||||
{
|
||||
label: `{{t('Continue when "Yes"', { ns: "${NAMESPACE}" })}}`,
|
||||
key: 'rejectOnFalse',
|
||||
value: { rejectOnFalse: true },
|
||||
presetFieldset = {
|
||||
rejectOnFalse: {
|
||||
type: 'boolean',
|
||||
title: `{{t("Mode", { ns: "${NAMESPACE}" })}}`,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Radio.Group',
|
||||
enum: [
|
||||
{
|
||||
label: `{{t('Continue when "Yes"', { ns: "${NAMESPACE}" })}}`,
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
label: `{{t('Branch into "Yes" and "No"', { ns: "${NAMESPACE}" })}}`,
|
||||
value: false,
|
||||
},
|
||||
],
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
label: `{{t('Branch into "Yes" and "No"', { ns: "${NAMESPACE}" })}}`,
|
||||
key: 'branch',
|
||||
value: { rejectOnFalse: false },
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
branching = ({ rejectOnFalse = true } = {}) => {
|
||||
return rejectOnFalse
|
||||
? false
|
||||
: [
|
||||
{
|
||||
label: `{{t('After end of branches', { ns: "${NAMESPACE}" })}}`,
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
label: `{{t('Inside of "Yes" branch', { ns: "${NAMESPACE}" })}}`,
|
||||
value: BRANCH_INDEX.ON_TRUE,
|
||||
},
|
||||
{
|
||||
label: `{{t('Inside of "No" branch', { ns: "${NAMESPACE}" })}}`,
|
||||
value: BRANCH_INDEX.ON_FALSE,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
scope = {
|
||||
renderEngineReference,
|
||||
|
@ -34,7 +34,7 @@ import {
|
||||
import { parse, str2moment } from '@nocobase/utils/client';
|
||||
|
||||
import WorkflowPlugin from '..';
|
||||
import { AddButton } from '../AddButton';
|
||||
import { AddButton } from '../AddNodeContext';
|
||||
import { useFlowContext } from '../FlowContext';
|
||||
import { DrawerDescription } from '../components/DrawerDescription';
|
||||
import { StatusButton } from '../components/StatusButton';
|
||||
@ -51,27 +51,40 @@ export type NodeAvailableContext = {
|
||||
branchIndex: number;
|
||||
};
|
||||
|
||||
type Config = Record<string, any>;
|
||||
|
||||
type Options = { label: string; value: any }[];
|
||||
|
||||
export abstract class Instruction {
|
||||
title: string;
|
||||
type: string;
|
||||
group: string;
|
||||
description?: string;
|
||||
/**
|
||||
* @experimental
|
||||
* @deprecated migrate to `presetFieldset` instead
|
||||
*/
|
||||
options?: { label: string; value: any; key: string }[];
|
||||
fieldset: Record<string, ISchema>;
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
presetFieldset?: Record<string, ISchema>;
|
||||
/**
|
||||
* To presentation if the instruction is creating a branch
|
||||
* @experimental
|
||||
*/
|
||||
branching?: boolean | Options | ((config: Config) => boolean | Options);
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
view?: ISchema;
|
||||
scope?: { [key: string]: any };
|
||||
components?: { [key: string]: any };
|
||||
scope?: Record<string, any>;
|
||||
components?: Record<string, any>;
|
||||
Component?(props): JSX.Element;
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
createDefaultConfig?(): Record<string, any> {
|
||||
createDefaultConfig?(): Config {
|
||||
return {};
|
||||
}
|
||||
useVariables?(node, options?: UseVariableOptions): VariableOption;
|
||||
@ -243,6 +256,7 @@ export function RemoveButton() {
|
||||
icon={<DeleteOutlined />}
|
||||
onClick={onRemove}
|
||||
className="workflow-node-remove-button"
|
||||
size="small"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -568,19 +582,18 @@ export function NodeDefaultView(props) {
|
||||
'Node with unknown type will cause error. Please delete it or check plugin which provide this type.',
|
||||
)}
|
||||
>
|
||||
<div
|
||||
role="button"
|
||||
aria-label={`_untyped-${editingTitle}`}
|
||||
className={cx(styles.nodeCardClass, 'invalid')}
|
||||
onClick={onOpenDrawer}
|
||||
>
|
||||
<div className={cx(styles.nodeMetaClass, 'workflow-node-meta')}>
|
||||
<Tag color="error">{lang('Unknown node')}</Tag>
|
||||
<span className="workflow-node-id">{data.id}</span>
|
||||
<div role="button" aria-label={`_untyped-${editingTitle}`} className={cx(styles.nodeCardClass, 'invalid')}>
|
||||
<div className={styles.nodeHeaderClass}>
|
||||
<div className={cx(styles.nodeMetaClass, 'workflow-node-meta')}>
|
||||
<Tag color="error">{lang('Unknown node')}</Tag>
|
||||
<span className="workflow-node-id">{data.id}</span>
|
||||
</div>
|
||||
<div className="workflow-node-actions">
|
||||
<RemoveButton />
|
||||
<JobButton />
|
||||
</div>
|
||||
</div>
|
||||
<Input.TextArea value={editingTitle} disabled autoSize />
|
||||
<RemoveButton />
|
||||
<JobButton />
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
@ -597,9 +610,15 @@ export function NodeDefaultView(props) {
|
||||
className={cx(styles.nodeCardClass, { configuring: editingConfig })}
|
||||
onClick={onOpenDrawer}
|
||||
>
|
||||
<div className={cx(styles.nodeMetaClass, 'workflow-node-meta')}>
|
||||
<Tag>{typeTitle}</Tag>
|
||||
<span className="workflow-node-id">{data.id}</span>
|
||||
<div className={styles.nodeHeaderClass}>
|
||||
<div className={cx(styles.nodeMetaClass, 'workflow-node-meta')}>
|
||||
<Tag>{typeTitle}</Tag>
|
||||
<span className="workflow-node-id">{data.id}</span>
|
||||
</div>
|
||||
<div className="workflow-node-actions">
|
||||
<RemoveButton />
|
||||
<JobButton />
|
||||
</div>
|
||||
</div>
|
||||
<Input.TextArea
|
||||
disabled={workflow.executed}
|
||||
@ -608,8 +627,6 @@ export function NodeDefaultView(props) {
|
||||
onBlur={(ev) => onChangeTitle(ev.target.value)}
|
||||
autoSize
|
||||
/>
|
||||
<RemoveButton />
|
||||
<JobButton />
|
||||
<ActionContextProvider
|
||||
value={{
|
||||
visible: editingConfig,
|
||||
|
@ -263,8 +263,8 @@ const useStyles = createStyles(({ css, token }) => {
|
||||
.workflow-node-remove-button {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0.5em;
|
||||
top: 0.5em;
|
||||
right: 0;
|
||||
top: 0;
|
||||
color: ${token.colorText};
|
||||
|
||||
&[disabled] {
|
||||
@ -312,19 +312,24 @@ const useStyles = createStyles(({ css, token }) => {
|
||||
nodeJobButtonClass: css`
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: calc(1em - 1px);
|
||||
right: 1em;
|
||||
top: 0;
|
||||
right: 0;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: ${token.colorTextLightSolid};
|
||||
`,
|
||||
|
||||
nodeHeaderClass: css`
|
||||
position: relative;
|
||||
display: flex;
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
.workflow-node-actions {
|
||||
position: relative;
|
||||
}
|
||||
`,
|
||||
|
||||
nodeMetaClass: css`
|
||||
margin-bottom: 0.5em;
|
||||
flex-grow: 1;
|
||||
|
||||
.workflow-node-id {
|
||||
color: ${token.colorTextDescription};
|
||||
@ -352,7 +357,6 @@ const useStyles = createStyles(({ css, token }) => {
|
||||
`,
|
||||
|
||||
nodeJobResultClass: css`
|
||||
padding: 1em;
|
||||
background-color: #f3f3f3;
|
||||
`,
|
||||
|
||||
|
@ -240,8 +240,10 @@ export const TriggerConfig = () => {
|
||||
className={cx(styles.nodeCardClass, 'invalid')}
|
||||
onClick={onOpenDrawer}
|
||||
>
|
||||
<div className={cx(styles.nodeMetaClass, 'workflow-node-meta')}>
|
||||
<Tag color="error">{lang('Unknown trigger')}</Tag>
|
||||
<div className={styles.nodeHeaderClass}>
|
||||
<div className={cx(styles.nodeMetaClass, 'workflow-node-meta')}>
|
||||
<Tag color="error">{lang('Unknown trigger')}</Tag>
|
||||
</div>
|
||||
</div>
|
||||
<div className="workflow-node-title">
|
||||
<Input.TextArea value={editingTitle} disabled autoSize />
|
||||
@ -260,11 +262,16 @@ export const TriggerConfig = () => {
|
||||
className={cx(styles.nodeCardClass)}
|
||||
onClick={onOpenDrawer}
|
||||
>
|
||||
<div className={cx(styles.nodeMetaClass, 'workflow-node-meta')}>
|
||||
<Tag color="gold">
|
||||
<ThunderboltOutlined />
|
||||
<span className="type">{compile(trigger.title)}</span>
|
||||
</Tag>
|
||||
<div className={styles.nodeHeaderClass}>
|
||||
<div className={cx(styles.nodeMetaClass, 'workflow-node-meta')}>
|
||||
<Tag color="gold">
|
||||
<ThunderboltOutlined />
|
||||
<span className="type">{compile(trigger.title)}</span>
|
||||
</Tag>
|
||||
</div>
|
||||
<div className="workflow-node-actions">
|
||||
<TriggerExecution />
|
||||
</div>
|
||||
</div>
|
||||
<div className="workflow-node-title">
|
||||
<Input.TextArea
|
||||
@ -275,7 +282,6 @@ export const TriggerConfig = () => {
|
||||
disabled={workflow.executed}
|
||||
/>
|
||||
</div>
|
||||
<TriggerExecution />
|
||||
<ActionContextProvider
|
||||
value={{
|
||||
visible: editingConfig,
|
||||
|
@ -160,6 +160,8 @@
|
||||
"Continue when \"Yes\"": "“是”则继续",
|
||||
"Branch into \"Yes\" and \"No\"": "“是”和“否”分别继续",
|
||||
"Condition expression": "条件表达式",
|
||||
"Inside of \"Yes\" branch": "“是”分支内",
|
||||
"Inside of \"No\" branch": "“否”分支内",
|
||||
"Create record": "新增数据",
|
||||
"Add new record to a collection. You can use variables from upstream nodes to assign values to fields.":
|
||||
"向一个数据表中添加新的数据。可以使用上游节点里的变量为字段赋值。",
|
||||
@ -206,5 +208,10 @@
|
||||
"Succeeded": "成功",
|
||||
"Test run": "测试执行",
|
||||
"Test run will do the actual data manipulating or API calling, please use with caution.": "测试执行会进行实际的数据操作或 API 调用,请谨慎使用。",
|
||||
"No variable": "无变量"
|
||||
"No variable": "无变量",
|
||||
|
||||
"Add node": "添加节点",
|
||||
"Move all downstream nodes to": "将所有下游节点移至",
|
||||
"After end of branches": "分支结束后",
|
||||
"Inside of branch": "分支内"
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ function make(name, mod) {
|
||||
}
|
||||
|
||||
export default function ({ app }) {
|
||||
app.actions({
|
||||
app.resourceManager.registerActionHandlers({
|
||||
...make('workflows', workflows),
|
||||
...make('workflows.nodes', {
|
||||
create: nodes.create,
|
||||
|
Loading…
Reference in New Issue
Block a user