From c4dff979accd52ad28b44e9a692557ea4d687b4f Mon Sep 17 00:00:00 2001 From: PiEgg Date: Tue, 16 Jun 2026 17:06:57 +0800 Subject: [PATCH] refactor(plugin-workflow): migrate end node config to v2 (#9795) --- .../nodes/__tests__/endFieldset.test.tsx | 34 +++++++++++++++++++ .../nodes/__tests__/endInstruction.test.ts | 30 ++++++++++++++++ .../src/client-v2/nodes/components/end.tsx | 33 ++++++++++++++++++ .../src/client-v2/nodes/end.tsx | 2 ++ .../plugin-workflow/src/client/nodes/end.tsx | 30 ++-------------- 5 files changed, 101 insertions(+), 28 deletions(-) create mode 100644 packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/__tests__/endFieldset.test.tsx create mode 100644 packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/__tests__/endInstruction.test.ts create mode 100644 packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/components/end.tsx diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/__tests__/endFieldset.test.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/__tests__/endFieldset.test.tsx new file mode 100644 index 00000000000..d82f72eb424 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/__tests__/endFieldset.test.tsx @@ -0,0 +1,34 @@ +/** + * 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 from 'react'; +import { describe, expect, it, vi } from 'vitest'; +import { render, screen } from '@testing-library/react'; +import { Form } from 'antd'; +import { EndFieldset } from '../components/end'; + +vi.mock('../../locale', () => ({ + NAMESPACE: 'workflow', + useT: () => (key: string) => key, +})); + +describe('EndFieldset', () => { + it('renders the v1-aligned end status options and default value', () => { + render( +
+ + , + ); + + expect(screen.getByText('End status')).toBeInTheDocument(); + expect(screen.getByRole('radio', { name: 'Succeeded' })).toBeInTheDocument(); + expect(screen.getByRole('radio', { name: 'Failed' })).toBeInTheDocument(); + expect(screen.getByRole('radio', { name: 'Succeeded' })).toBeChecked(); + }); +}); diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/__tests__/endInstruction.test.ts b/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/__tests__/endInstruction.test.ts new file mode 100644 index 00000000000..d895ce7ee13 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/__tests__/endInstruction.test.ts @@ -0,0 +1,30 @@ +/** + * 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 { describe, expect, it } from 'vitest'; +import V2EndInstruction from '../end'; +import V1EndInstruction from '../../../client/nodes/end'; + +describe('EndInstruction', () => { + it('keeps the v1 node as a thin compatibility entry over the v2 implementation', () => { + const instruction = new V1EndInstruction(); + + expect(instruction).toBeInstanceOf(V2EndInstruction); + expect(typeof instruction.FieldsetLoader).toBe('function'); + }); + + it('preserves the v1 metadata in the v2 instruction', () => { + const instruction = new V2EndInstruction(); + + expect(instruction.type).toBe('end'); + expect(instruction.group).toBe('control'); + expect(instruction.description).toBe('{{t("End the process immediately, with set status.", { ns: "workflow" })}}'); + expect(instruction.end).toBe(true); + }); +}); diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/components/end.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/components/end.tsx new file mode 100644 index 00000000000..965a041c1bf --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/components/end.tsx @@ -0,0 +1,33 @@ +/** + * 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 from 'react'; +import { Form, Radio } from 'antd'; +import { JOB_STATUS } from '../../components/jobStatus'; +import { useT } from '../../locale'; + +const END_STATUS_OPTIONS = [ + { value: JOB_STATUS.RESOLVED, label: 'Succeeded' }, + { value: JOB_STATUS.FAILED, label: 'Failed' }, +] as const; + +export function EndFieldset() { + const t = useT(); + + return ( + + ({ ...option, label: t(option.label) }))} /> + + ); +} diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/end.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/end.tsx index 5ff59263fd4..3a8e85ad729 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/end.tsx +++ b/packages/plugins/@nocobase/plugin-workflow/src/client-v2/nodes/end.tsx @@ -18,6 +18,8 @@ export default class extends Instruction { type = 'end'; title = t('End process'); group = 'control'; + description = t('End the process immediately, with set status.'); icon = (); + FieldsetLoader = () => import('./components/end').then((m) => ({ default: m.EndFieldset })); end = true; } diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client/nodes/end.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client/nodes/end.tsx index 7011285ff77..68af293c2b5 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/client/nodes/end.tsx +++ b/packages/plugins/@nocobase/plugin-workflow/src/client/nodes/end.tsx @@ -7,32 +7,6 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import React from 'react'; -import { StopOutlined } from '@ant-design/icons'; +import V2EndInstruction from '../../client-v2/nodes/end'; -import { Instruction } from '.'; -import { NAMESPACE } from '../locale'; -import { JOB_STATUS } from '../constants'; - -export default class extends Instruction { - title = `{{t("End process", { ns: "${NAMESPACE}" })}}`; - type = 'end'; - group = 'control'; - description = `{{t("End the process immediately, with set status.", { ns: "${NAMESPACE}" })}}`; - icon = (); - fieldset = { - endStatus: { - type: 'number', - title: `{{t("End status", { ns: "${NAMESPACE}" })}}`, - 'x-decorator': 'FormItem', - 'x-component': 'Radio.Group', - enum: [ - { label: `{{t("Succeeded", { ns: "${NAMESPACE}" })}}`, value: JOB_STATUS.RESOLVED }, - { label: `{{t("Failed", { ns: "${NAMESPACE}" })}}`, value: JOB_STATUS.FAILED }, - ], - required: true, - default: JOB_STATUS.RESOLVED, - }, - }; - end = true; -} +export default class extends V2EndInstruction {}