From c2b121cda6214a6dd4a088f9e6dcbb5268d5576f Mon Sep 17 00:00:00 2001 From: Junyi Date: Wed, 6 Mar 2024 14:42:20 +0800 Subject: [PATCH] feat(plugin-workflow-form-trigger): add trigger button to all single record action bar (#3563) * feat(plugin-workflow-form-trigger): add trigger button to all single record actionbar * fix(plugin-workflow-form-trigger): fix button style and triggering * fix(plugin-workflow): fix unused hook ref in workflow * fix(plugin-workflow-form-trigger): fix button style * refactor(plugin-workflow-action-trigger): change plugin name * fix(plugin-workflow-action-trigger): fix unmigrated stuff * fix(plugin-workflow-action-trigger): fix test case * fix(plugin-workflow-action-trigger): fix test case * fix(presets): fix package name * fix(plugin-workflow-action-trigger): fix e2e test and migration * fix(plugin-workflow-action-trigger): fix migration * fix(plugin-workflow-action-trigger): fix migration * fix(plugin-workflow-action-trigger): fix migration * feat(plugin-workflow-action-trigger): add destroy to trigger * fix(plugin-workflow-action-trigger): fix appends select * fix(plugin-workflow-action-trigger): remove support for destroy action * fix(plugin-workflow-action-trigger): fix collection check * fix(plugin-workflow-action-trigger): fix test case * fix(plugin-workflow-action-trigger): fix test case * fix(plugin-workflow-action-trigger): fix test case --- .../client/src/block-provider/hooks/index.ts | 11 ++ .../UpdateRecordActionInitializer.tsx | 1 + .../customizeUpdateRecordActionSettings.tsx | 11 ++ .../DetailsActionInitializers.tsx | 10 ++ .../form/createFormActionInitializers.tsx | 2 - .../form/formActionInitializers.tsx | 7 -- .../form/updateFormActionInitializers.tsx | 2 - .../CalendarFormActionInitializers.tsx | 1 + .../LICENSE | 0 .../README.md | 0 .../README.zh-CN.md | 0 .../client.d.ts | 0 .../client.js | 0 .../package.json | 28 +++++ .../server.d.ts | 0 .../server.js | 0 .../src/client/ActionTrigger.tsx} | 16 +-- .../src/client/__e2e__/configuration.test.ts | 34 +++--- .../src/client/__e2e__/workflowCRUD.test.ts | 18 ++-- .../src/client/index.ts | 100 ++++++++++++++++++ .../src/index.ts | 0 .../src/locale/en-US.json | 0 .../src/locale/index.ts | 2 +- .../src/locale/ko_KR.json | 0 .../src/locale/zh-CN.json | 10 ++ .../src/server/ActionTrigger.ts} | 22 ++-- .../src/server/Plugin.ts | 11 ++ .../src/server/__tests__/trigger.test.ts | 75 +++++++++---- .../src/server/index.ts | 0 .../migrations/20240227172623-change-name.ts | 22 ++++ .../plugin-workflow-form-trigger/package.json | 28 ----- .../src/client/index.ts | 18 ---- .../src/locale/zh-CN.json | 10 -- .../src/server/Plugin.ts | 11 -- ...FormTriggerWorkflowActionInitializerV2.tsx | 28 ----- .../src/client/components/index.ts | 1 - .../hooks/useTriggerWorkflowActionProps.ts | 56 ++++++++++ .../plugin-workflow/src/client/index.tsx | 12 +-- .../plugin-workflow/src/server/utils.ts | 2 +- packages/presets/nocobase/package.json | 2 +- packages/presets/nocobase/src/server/index.ts | 2 +- .../migrations/20240227172623-change-name.ts | 14 +++ 42 files changed, 383 insertions(+), 184 deletions(-) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/LICENSE (100%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/README.md (100%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/README.zh-CN.md (100%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/client.d.ts (100%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/client.js (100%) create mode 100644 packages/plugins/@nocobase/plugin-workflow-action-trigger/package.json rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/server.d.ts (100%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/server.js (100%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger/src/client/FormTrigger.tsx => plugin-workflow-action-trigger/src/client/ActionTrigger.tsx} (84%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/src/client/__e2e__/configuration.test.ts (96%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/src/client/__e2e__/workflowCRUD.test.ts (94%) create mode 100644 packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/index.ts rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/src/index.ts (100%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/src/locale/en-US.json (100%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/src/locale/index.ts (83%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/src/locale/ko_KR.json (100%) create mode 100644 packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/zh-CN.json rename packages/plugins/@nocobase/{plugin-workflow-form-trigger/src/server/FormTrigger.ts => plugin-workflow-action-trigger/src/server/ActionTrigger.ts} (88%) create mode 100644 packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/Plugin.ts rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/src/server/__tests__/trigger.test.ts (89%) rename packages/plugins/@nocobase/{plugin-workflow-form-trigger => plugin-workflow-action-trigger}/src/server/index.ts (100%) create mode 100644 packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/migrations/20240227172623-change-name.ts delete mode 100644 packages/plugins/@nocobase/plugin-workflow-form-trigger/package.json delete mode 100644 packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/index.ts delete mode 100644 packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/zh-CN.json delete mode 100644 packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/Plugin.ts delete mode 100644 packages/plugins/@nocobase/plugin-workflow/src/client/components/FormTriggerWorkflowActionInitializerV2.tsx create mode 100644 packages/presets/nocobase/src/server/migrations/20240227172623-change-name.ts diff --git a/packages/core/client/src/block-provider/hooks/index.ts b/packages/core/client/src/block-provider/hooks/index.ts index 3d3a3eb42..3162fe9da 100644 --- a/packages/core/client/src/block-provider/hooks/index.ts +++ b/packages/core/client/src/block-provider/hooks/index.ts @@ -507,6 +507,7 @@ export const useCustomizeUpdateActionProps = () => { assignedValues: originalAssignedValues = {}, onSuccess, skipValidator, + triggerWorkflows, } = actionSchema?.['x-action-settings'] ?? {}; const assignedValues = {}; @@ -537,6 +538,10 @@ export const useCustomizeUpdateActionProps = () => { await resource.update({ filterByTk, values: { ...assignedValues }, + // TODO(refactor): should change to inject by plugin + triggerWorkflows: triggerWorkflows?.length + ? triggerWorkflows.map((row) => [row.workflowKey, row.context].filter(Boolean).join('!')).join(',') + : undefined, }); service?.refresh?.(); if (!(resource instanceof TableFieldResource)) { @@ -902,10 +907,16 @@ export const useDestroyActionProps = () => { const { resource, service, block, __parent } = useBlockRequestContext(); const { setVisible } = useActionContext(); const data = useParamsFromRecord(); + const actionSchema = useFieldSchema(); return { async onClick() { + const { triggerWorkflows } = actionSchema?.['x-action-settings'] ?? {}; await resource.destroy({ filterByTk, + // TODO(refactor): should change to inject by plugin + triggerWorkflows: triggerWorkflows?.length + ? triggerWorkflows.map((row) => [row.workflowKey, row.context].filter(Boolean).join('!')).join(',') + : undefined, ...data, }); diff --git a/packages/core/client/src/modules/actions/update-record/UpdateRecordActionInitializer.tsx b/packages/core/client/src/modules/actions/update-record/UpdateRecordActionInitializer.tsx index 0b099eefc..47153ecb8 100644 --- a/packages/core/client/src/modules/actions/update-record/UpdateRecordActionInitializer.tsx +++ b/packages/core/client/src/modules/actions/update-record/UpdateRecordActionInitializer.tsx @@ -19,6 +19,7 @@ export const UpdateRecordActionInitializer = (props) => { redirecting: false, successMessage: '{{t("Updated successfully")}}', }, + triggerWorkflows: [], }, 'x-component-props': { useProps: '{{ useCustomizeUpdateActionProps }}', diff --git a/packages/core/client/src/modules/actions/update-record/customizeUpdateRecordActionSettings.tsx b/packages/core/client/src/modules/actions/update-record/customizeUpdateRecordActionSettings.tsx index f5e1a9a94..86ed008fe 100644 --- a/packages/core/client/src/modules/actions/update-record/customizeUpdateRecordActionSettings.tsx +++ b/packages/core/client/src/modules/actions/update-record/customizeUpdateRecordActionSettings.tsx @@ -1,3 +1,5 @@ +import { isValid } from '@formily/shared'; +import { useFieldSchema } from '@formily/react'; import { useSchemaToolbar } from '../../../application'; import { SchemaSettings } from '../../../application/schema-settings/SchemaSettings'; import { useCollection_deprecated } from '../../../collection-manager'; @@ -7,6 +9,7 @@ import { ButtonEditor, RemoveButton, SecondConFirm, + WorkflowConfig, } from '../../../schema-component/antd/action/Action.Designer'; import { SchemaSettingsLinkageRules } from '../../../schema-settings'; @@ -45,6 +48,14 @@ export const customizeUpdateRecordActionSettings = new SchemaSettings({ name: 'afterSuccessfulSubmission', Component: AfterSuccess, }, + { + name: 'workflowConfig', + Component: WorkflowConfig, + useVisible() { + const fieldSchema = useFieldSchema(); + return isValid(fieldSchema?.['x-action-settings']?.triggerWorkflows); + }, + }, { name: 'delete', sort: 100, diff --git a/packages/core/client/src/modules/blocks/data-blocks/details-multi/DetailsActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/details-multi/DetailsActionInitializers.tsx index a6041fc06..0e8da5417 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/details-multi/DetailsActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/details-multi/DetailsActionInitializers.tsx @@ -37,5 +37,15 @@ export const detailsActionInitializers = new SchemaInitializer({ }, ], }, + { + name: 'divider', + type: 'divider', + }, + { + type: 'subMenu', + name: 'customize', + title: '{{t("Customize")}}', + children: [], + }, ], }); diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/createFormActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/createFormActionInitializers.tsx index 6c83d1d63..87b57abbe 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/createFormActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/createFormActionInitializers.tsx @@ -1,5 +1,4 @@ import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer'; -import { formTriggerWorkflowActionInitializerV2 } from './formActionInitializers'; export const createFormActionInitializers = new SchemaInitializer({ name: 'CreateFormActionInitializers', @@ -35,7 +34,6 @@ export const createFormActionInitializers = new SchemaInitializer({ title: '{{t("Save record")}}', Component: 'SaveRecordActionInitializer', }, - formTriggerWorkflowActionInitializerV2, { name: 'customRequest', title: '{{t("Custom request")}}', diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/formActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/formActionInitializers.tsx index 13ac761f2..a16659f4a 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/formActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/formActionInitializers.tsx @@ -1,12 +1,6 @@ import { SchemaInitializerItemType } from '../../../../application'; import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer'; -export const formTriggerWorkflowActionInitializerV2: SchemaInitializerItemType = { - name: 'submitToWorkflow', - title: '{{t("Submit to workflow", { ns: "workflow" })}}', - Component: 'FormTriggerWorkflowActionInitializerV2', -}; - // 表单的操作配置 export const formActionInitializers = new SchemaInitializer({ name: 'FormActionInitializers', @@ -42,7 +36,6 @@ export const formActionInitializers = new SchemaInitializer({ title: '{{t("Save record")}}', Component: 'SaveRecordActionInitializer', }, - formTriggerWorkflowActionInitializerV2, { name: 'customRequest', title: '{{t("Custom request")}}', diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/updateFormActionInitializers.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/updateFormActionInitializers.tsx index 2eaeab61f..56aaa47fc 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/updateFormActionInitializers.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/updateFormActionInitializers.tsx @@ -1,5 +1,4 @@ import { SchemaInitializer } from '../../../../application/schema-initializer/SchemaInitializer'; -import { formTriggerWorkflowActionInitializerV2 } from './formActionInitializers'; export const updateFormActionInitializers = new SchemaInitializer({ name: 'UpdateFormActionInitializers', @@ -45,7 +44,6 @@ export const updateFormActionInitializers = new SchemaInitializer({ title: '{{t("Save record")}}', Component: 'SaveRecordActionInitializer', }, - formTriggerWorkflowActionInitializerV2, { type: 'item', name: 'customRequest', diff --git a/packages/plugins/@nocobase/plugin-calendar/src/client/schema-initializer/initializers/CalendarFormActionInitializers.tsx b/packages/plugins/@nocobase/plugin-calendar/src/client/schema-initializer/initializers/CalendarFormActionInitializers.tsx index 86fc1239b..97832dea4 100644 --- a/packages/plugins/@nocobase/plugin-calendar/src/client/schema-initializer/initializers/CalendarFormActionInitializers.tsx +++ b/packages/plugins/@nocobase/plugin-calendar/src/client/schema-initializer/initializers/CalendarFormActionInitializers.tsx @@ -139,6 +139,7 @@ export const CalendarFormActionInitializers: SchemaInitializer = new SchemaIniti redirecting: false, successMessage: generateNTemplate('Updated successfully'), }, + triggerWorkflows: [], }, 'x-component-props': { useProps: '{{ useCustomizeUpdateActionProps }}', diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/LICENSE b/packages/plugins/@nocobase/plugin-workflow-action-trigger/LICENSE similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/LICENSE rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/LICENSE diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/README.md b/packages/plugins/@nocobase/plugin-workflow-action-trigger/README.md similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/README.md rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/README.md diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/README.zh-CN.md b/packages/plugins/@nocobase/plugin-workflow-action-trigger/README.zh-CN.md similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/README.zh-CN.md rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/README.zh-CN.md diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/client.d.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/client.d.ts similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/client.d.ts rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/client.d.ts diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/client.js b/packages/plugins/@nocobase/plugin-workflow-action-trigger/client.js similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/client.js rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/client.js diff --git a/packages/plugins/@nocobase/plugin-workflow-action-trigger/package.json b/packages/plugins/@nocobase/plugin-workflow-action-trigger/package.json new file mode 100644 index 000000000..608d9c969 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/package.json @@ -0,0 +1,28 @@ +{ + "name": "@nocobase/plugin-workflow-action-trigger", + "displayName": "Workflow: Action trigger", + "displayName.zh-CN": "工作流:数据操作触发器", + "description": "Bind action buttons to trigger workflow events when clicked.", + "description.zh-CN": "可对数据操作按钮绑定,在点击后触发对应的工作流事件。", + "version": "0.20.0-alpha.5", + "license": "AGPL-3.0", + "main": "./dist/server/index.js", + "homepage": "https://docs.nocobase.com/plugins/workflow-action-trigger", + "homepage.zh-CN": "https://docs-cn.nocobase.com/plugins/workflow-action-trigger", + "devDependencies": { + "antd": "5.x", + "react": "18.x", + "react-i18next": "^11.15.1" + }, + "peerDependencies": { + "@nocobase/client": "0.x", + "@nocobase/database": "0.x", + "@nocobase/plugin-workflow": ">=0.17.0-alpha.3", + "@nocobase/server": "0.x", + "@nocobase/test": "0.x" + }, + "gitHead": "d0b4efe4be55f8c79a98a331d99d9f8cf99021a1", + "keywords": [ + "Workflow" + ] +} diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/server.d.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/server.d.ts similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/server.d.ts rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/server.d.ts diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/server.js b/packages/plugins/@nocobase/plugin-workflow-action-trigger/server.js similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/server.js rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/server.js diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/FormTrigger.tsx b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/ActionTrigger.tsx similarity index 84% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/FormTrigger.tsx rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/ActionTrigger.tsx index c4c244afb..cbf88b9e7 100644 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/FormTrigger.tsx +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/ActionTrigger.tsx @@ -10,8 +10,8 @@ import { Trigger, CollectionBlockInitializer, getCollectionFieldOptions } from ' import { NAMESPACE, useLang } from '../locale'; export default class extends Trigger { - title = `{{t("Form event", { ns: "${NAMESPACE}" })}}`; - description = `{{t("Event triggers when submitted a workflow bound form action.", { ns: "${NAMESPACE}" })}}`; + title = `{{t("Action event", { ns: "${NAMESPACE}" })}}`; + description = `{{t("Triggers after specific operations on data are submitted, such as create, update, delete, etc., or directly submitting a record to the workflow.", { ns: "${NAMESPACE}" })}}`; fieldset = { collection: { type: 'string', @@ -21,8 +21,8 @@ export default class extends Trigger { 'x-component-props': { className: 'auto-width', }, - title: `{{t("Form data model", { ns: "${NAMESPACE}" })}}`, - description: `{{t("Use a collection to match form data.", { ns: "${NAMESPACE}" })}}`, + title: `{{t("Collection", { ns: "${NAMESPACE}" })}}`, + description: `{{t("Which collection record belongs to.", { ns: "${NAMESPACE}" })}}`, 'x-reactions': [ { target: 'appends', @@ -38,7 +38,7 @@ export default class extends Trigger { appends: { type: 'array', title: `{{t("Associations to use", { ns: "${NAMESPACE}" })}}`, - description: `{{t("Please select the associated fields that need to be accessed in subsequent nodes. With more than two levels of to-many associations may cause performance issue, please use with caution.", { ns: "${NAMESPACE}" })}}`, + description: `{{t("Please select the associated fields that need to be accessed in subsequent nodes. With more than two levels of to-many associations may cause performance issue, please use with caution.", { ns: "workflow" })}}`, 'x-decorator': 'FormItem', 'x-component': 'AppendsTreeSelect', 'x-component-props': { @@ -65,7 +65,7 @@ export default class extends Trigger { useCollectionDataSource, }; isActionTriggerable = (config, context) => { - return ['create', 'update'].includes(context.action); + return ['create', 'update', 'customize:update', 'customize:triggerWorkflows'].includes(context.action); }; useVariables(config, options) { // eslint-disable-next-line react-hooks/rules-of-hooks @@ -75,9 +75,9 @@ export default class extends Trigger { // eslint-disable-next-line react-hooks/rules-of-hooks const langTriggerData = useLang('Trigger data'); // eslint-disable-next-line react-hooks/rules-of-hooks - const langUserSubmittedForm = useLang('User submitted form'); + const langUserSubmittedForm = useLang('User submitted action'); // eslint-disable-next-line react-hooks/rules-of-hooks - const langRoleSubmittedForm = useLang('Role of user submitted form'); + const langRoleSubmittedForm = useLang('Role of user submitted action'); const rootFields = [ { collectionName: config.collection, diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/configuration.test.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/configuration.test.ts similarity index 96% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/configuration.test.ts rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/configuration.test.ts index bc8dc5c62..b9fc86bb4 100644 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/configuration.test.ts +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/configuration.test.ts @@ -38,7 +38,7 @@ test.describe('Configuration page to configure the Trigger node', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -130,7 +130,7 @@ test.describe('Configuration page to configure the Trigger node', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -182,7 +182,7 @@ test.describe('Configuration page to configure the Trigger node', () => { await page.getByRole('button', { name: 'Submit to workflow' }).hover(); await page .getByRole('button', { - name: `designer-schema-settings-Action-actionSettings:submitToWorkflow-${triggerNodeCollectionName}`, + name: `designer-schema-settings-Action-Action.Designer-${triggerNodeCollectionName}`, }) .hover(); await page.getByRole('menuitem', { name: 'Bind workflows' }).click(); @@ -211,7 +211,7 @@ test.describe('Configuration page to configure the Trigger node', () => { }); test.describe('Configuration Page Path Jump Workflow Management Page', () => { - test('Form event Workflow Configuration Page Path Jump Workflow Management Page', async ({ + test('Action event Workflow Configuration Page Path Jump Workflow Management Page', async ({ page, mockPage, mockCollections, @@ -232,7 +232,7 @@ test.describe('Configuration Page Path Jump Workflow Management Page', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -254,7 +254,7 @@ test.describe('Configuration Page Path Jump Workflow Management Page', () => { await apiDeleteWorkflow(workflowId); }); - test('Form event Workflow History Version Configuration Page Path Jump Workflow Management Page', async ({ + test('Action event Workflow History Version Configuration Page Path Jump Workflow Management Page', async ({ page, mockPage, mockCollections, @@ -278,7 +278,7 @@ test.describe('Configuration Page Path Jump Workflow Management Page', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -320,7 +320,7 @@ test.describe('Configuration Page Path Jump Workflow Management Page', () => { await apiDeleteWorkflow(workflowId); }); - test('Form event Workflow Execution Log Page Path Jump Workflow Management Page', async ({ + test('Action event Workflow Execution Log Page Path Jump Workflow Management Page', async ({ page, mockPage, mockCollections, @@ -344,7 +344,7 @@ test.describe('Configuration Page Path Jump Workflow Management Page', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -384,7 +384,7 @@ test.describe('Configuration Page Path Jump Workflow Management Page', () => { await apiDeleteWorkflow(workflowId); }); - test.skip('Form event Workflow Execution Log Page Path Jump Execution Log Screen', async ({ + test.skip('Action event Workflow Execution Log Page Path Jump Execution Log Screen', async ({ page, mockCollections, mockRecords, @@ -407,7 +407,7 @@ test.describe('Configuration Page Path Jump Workflow Management Page', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -451,7 +451,7 @@ test.describe('Configuration Page Path Jump Workflow Management Page', () => { test.describe('Configuration page version switching', () => {}); test.describe('Configuration page disable enable', () => { - test('Form event Workflow Add Data Trigger Disable Do Not Trigger', async ({ + test('Action event Workflow Add Data Trigger Disable Do Not Trigger', async ({ page, mockCollections, mockRecords, @@ -474,7 +474,7 @@ test.describe('Configuration page disable enable', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: false, }; const workflow = await apiCreateWorkflow(workflowData); @@ -522,7 +522,7 @@ test.describe('Configuration page disable enable', () => { await apiDeleteWorkflow(workflowId); }); - test('Form event Workflow Add Data Trigger Disable Enable Post Trigger', async ({ + test('Action event Workflow Add Data Trigger Disable Enable Post Trigger', async ({ page, mockCollections, mockRecords, @@ -545,7 +545,7 @@ test.describe('Configuration page disable enable', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -597,7 +597,7 @@ test.describe('Configuration page disable enable', () => { test.describe('Configuration page execution history', () => {}); test.describe('Configuration page copy to new version', () => { - test('Copy the Form event of the Configuration Trigger node', async ({ page, mockCollections, mockRecords }) => { + test('Copy the action event of the Configuration Trigger node', async ({ page, mockCollections, mockRecords }) => { //数据表后缀标识 const triggerNodeAppendText = faker.string.alphanumeric(5); @@ -616,7 +616,7 @@ test.describe('Configuration page copy to new version', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/workflowCRUD.test.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/workflowCRUD.test.ts similarity index 94% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/workflowCRUD.test.ts rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/workflowCRUD.test.ts index 1a3baa8d0..d94d61cd5 100644 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/workflowCRUD.test.ts +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/__e2e__/workflowCRUD.test.ts @@ -24,7 +24,7 @@ test.describe('Filter', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -47,7 +47,7 @@ test.describe('Filter', () => { }); test.describe('Add new', () => { - test('add new Form event', async ({ page }) => { + test('add new Action event', async ({ page }) => { // 添加工作流 await page.goto('/admin/settings/workflow'); await page.waitForLoadState('networkidle'); @@ -56,7 +56,7 @@ test.describe('Add new', () => { const workFlowName = faker.string.alphanumeric(5); await createWorkFlow.name.fill(workFlowName); await createWorkFlow.triggerType.click(); - await page.getByRole('option', { name: 'Form event' }).click(); + await page.getByRole('option', { name: 'Action event' }).click(); await page.getByLabel('action-Action-Submit-workflows').click(); // 3、预期结果:列表中出现新建的工作流 @@ -75,7 +75,7 @@ test.describe('Add new', () => { test.describe('Sync', () => {}); test.describe('Delete', () => { - test('delete Form event', async ({ page }) => { + test('delete Action event', async ({ page }) => { //添加工作流 const triggerNodeAppendText = faker.string.alphanumeric(5); const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText; @@ -83,7 +83,7 @@ test.describe('Delete', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -107,7 +107,7 @@ test.describe('Delete', () => { }); test.describe('Edit', () => { - test('edit Form event name', async ({ page }) => { + test('edit Action event name', async ({ page }) => { //添加工作流 const triggerNodeAppendText = faker.string.alphanumeric(5); let workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText; @@ -115,7 +115,7 @@ test.describe('Edit', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); @@ -140,7 +140,7 @@ test.describe('Edit', () => { }); test.describe('Duplicate', () => { - test('Duplicate Form event triggers with only unconfigured trigger nodes', async ({ page }) => { + test('Duplicate Action event triggers with only unconfigured trigger nodes', async ({ page }) => { //添加工作流 const triggerNodeAppendText = faker.string.alphanumeric(5); const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText; @@ -148,7 +148,7 @@ test.describe('Duplicate', () => { current: true, options: { deleteExecutionOnStatus: [] }, title: workFlowName, - type: 'form', + type: 'action', enabled: true, }; const workflow = await apiCreateWorkflow(workflowData); diff --git a/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/index.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/index.ts new file mode 100644 index 000000000..8b02ac516 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/client/index.ts @@ -0,0 +1,100 @@ +import { Plugin, SchemaInitializerItemType } from '@nocobase/client'; +import WorkflowPlugin, { + useTriggerWorkflowsActionProps, + useRecordTriggerWorkflowsActionProps, +} from '@nocobase/plugin-workflow/client'; + +import ActionTrigger from './ActionTrigger'; + +const submitToWorkflowActionInitializer: SchemaInitializerItemType = { + name: 'submitToWorkflow', + title: '{{t("Submit to workflow", { ns: "workflow" })}}', + Component: 'CustomizeActionInitializer', + schema: { + title: '{{t("Submit to workflow", { ns: "workflow" })}}', + 'x-component': 'Action', + 'x-component-props': { + useProps: '{{ useTriggerWorkflowsActionProps }}', + }, + 'x-designer': 'Action.Designer', + 'x-action-settings': { + // assignedValues: {}, + skipValidator: false, + onSuccess: { + manualClose: true, + redirecting: false, + successMessage: '{{t("Submitted successfully")}}', + }, + triggerWorkflows: [], + }, + 'x-action': 'customize:triggerWorkflows', + }, +}; + +const recordTriggerWorkflowActionInitializer: SchemaInitializerItemType = { + name: 'submitToWorkflow', + title: '{{t("Submit to workflow", { ns: "workflow" })}}', + Component: 'CustomizeActionInitializer', + schema: { + title: '{{t("Submit to workflow", { ns: "workflow" })}}', + 'x-component': 'Action', + 'x-component-props': { + useProps: '{{ useRecordTriggerWorkflowsActionProps }}', + }, + 'x-designer': 'Action.Designer', + 'x-action-settings': { + // assignedValues: {}, + onSuccess: { + manualClose: true, + redirecting: false, + successMessage: '{{t("Submitted successfully")}}', + }, + triggerWorkflows: [], + }, + 'x-action': 'customize:triggerWorkflows', + }, +}; + +const recordTriggerWorkflowActionLinkInitializer = { + ...recordTriggerWorkflowActionInitializer, + schema: { + ...recordTriggerWorkflowActionInitializer.schema, + 'x-component': 'Action.Link', + }, +}; + +export default class extends Plugin { + async load() { + const workflow = this.app.pm.get('workflow') as WorkflowPlugin; + workflow.registerTrigger('action', ActionTrigger); + + this.app.addScopes({ + useTriggerWorkflowsActionProps, + useRecordTriggerWorkflowsActionProps, + }); + + const FormActionInitializers = this.app.schemaInitializerManager.get('FormActionInitializers'); + FormActionInitializers.add('customize.submitToWorkflow', submitToWorkflowActionInitializer); + + const CreateFormActionInitializers = this.app.schemaInitializerManager.get('CreateFormActionInitializers'); + CreateFormActionInitializers.add('customize.submitToWorkflow', submitToWorkflowActionInitializer); + + const UpdateFormActionInitializers = this.app.schemaInitializerManager.get('UpdateFormActionInitializers'); + UpdateFormActionInitializers.add('customize.submitToWorkflow', submitToWorkflowActionInitializer); + + const DetailsActionInitializers = this.app.schemaInitializerManager.get('DetailsActionInitializers'); + DetailsActionInitializers.add('customize.submitToWorkflow', recordTriggerWorkflowActionInitializer); + + const ReadPrettyFormActionInitializers = this.app.schemaInitializerManager.get('ReadPrettyFormActionInitializers'); + ReadPrettyFormActionInitializers.add('customize.submitToWorkflow', recordTriggerWorkflowActionInitializer); + + const TableActionColumnInitializers = this.app.schemaInitializerManager.get('TableActionColumnInitializers'); + TableActionColumnInitializers.add('customize.submitToWorkflow', recordTriggerWorkflowActionLinkInitializer); + + const GridCardItemActionInitializers = this.app.schemaInitializerManager.get('GridCardItemActionInitializers'); + GridCardItemActionInitializers.add('customize.submitToWorkflow', recordTriggerWorkflowActionLinkInitializer); + + const ListItemActionInitializers = this.app.schemaInitializerManager.get('ListItemActionInitializers'); + ListItemActionInitializers.add('customize.submitToWorkflow', recordTriggerWorkflowActionLinkInitializer); + } +} diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/index.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/index.ts similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/index.ts rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/index.ts diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/en-US.json b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/en-US.json similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/en-US.json rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/en-US.json diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/index.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/index.ts similarity index 83% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/index.ts rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/index.ts index 01a1b0419..585419235 100644 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/index.ts +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/index.ts @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next'; -export const NAMESPACE = 'workflow-form-trigger'; +export const NAMESPACE = 'workflow-action-trigger'; export function useLang(key: string, options = {}) { const { t } = usePluginTranslation(options); diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/ko_KR.json b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/ko_KR.json similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/ko_KR.json rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/ko_KR.json diff --git a/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/zh-CN.json b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/zh-CN.json new file mode 100644 index 000000000..ee84a6c90 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/locale/zh-CN.json @@ -0,0 +1,10 @@ +{ + "Action event": "操作事件", + "Triggers after specific operations on data are submitted, such as create, update, delete, etc., or directly submitting a record to the workflow.": "在对数据的特定操作提交后触发,如创建、更新、删除等,或直接提交一条数据至工作流。", + "Collection": "数据表", + "Which collection record belongs to.": "数据所属的数据表。", + "Associations to use": "待使用的关系数据", + "Trigger data": "触发器数据", + "User submitted action": "提交操作的用户", + "Role of user submitted action": "提交操作用户的角色" +} diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/FormTrigger.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/ActionTrigger.ts similarity index 88% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/FormTrigger.ts rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/ActionTrigger.ts index 05e3e4718..49df2c69a 100644 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/FormTrigger.ts +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/ActionTrigger.ts @@ -63,7 +63,7 @@ export default class extends Trigger { filter: { key: triggers.map((trigger) => trigger[0]), current: true, - type: 'form', + type: 'action', enabled: true, }, }); @@ -91,15 +91,17 @@ export default class extends Trigger { } } const { collection, appends = [] } = workflow.config; - const model = payload.constructor; - if (collection !== model.collection.name) { - continue; - } - if (appends.length) { - payload = await model.collection.repository.findOne({ - filterByTk: payload.get(model.primaryKeyAttribute), - appends, - }); + const model = payload.constructor; + if (payload instanceof Model) { + if (collection !== model.collection.name) { + continue; + } + if (appends.length) { + payload = await model.collection.repository.findOne({ + filterByTk: payload.get(model.primaryKeyAttribute), + appends, + }); + } } // this.workflow.trigger(workflow, { data: toJSON(payload), ...userInfo }); event.push({ data: toJSON(payload), ...userInfo }); diff --git a/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/Plugin.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/Plugin.ts new file mode 100644 index 000000000..1c03fb7bc --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/Plugin.ts @@ -0,0 +1,11 @@ +import { Plugin } from '@nocobase/server'; +import WorkflowPlugin from '@nocobase/plugin-workflow'; + +import ActionTrigger from './ActionTrigger'; + +export default class extends Plugin { + async load() { + const workflowPlugin = this.app.pm.get(WorkflowPlugin) as WorkflowPlugin; + workflowPlugin.triggers.register('action', new ActionTrigger(workflowPlugin)); + } +} diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/__tests__/trigger.test.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/__tests__/trigger.test.ts similarity index 89% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/__tests__/trigger.test.ts rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/__tests__/trigger.test.ts index 8491e6240..90f8db997 100644 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/__tests__/trigger.test.ts +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/__tests__/trigger.test.ts @@ -5,7 +5,7 @@ import { MockServer } from '@nocobase/test'; import Plugin from '..'; -describe('workflow > form-trigge[r', () => { +describe('workflow > action-trigger', () => { let app: MockServer; let db: Database; let agent; @@ -20,7 +20,7 @@ describe('workflow > form-trigge[r', () => { app = await getApp({ plugins: ['users', 'auth', Plugin], }); - await app.getPlugin('auth').install(); + await app.pm.get('auth').install(); agent = app.agent(); db = app.db; WorkflowModel = db.getCollection('workflows').model; @@ -42,7 +42,7 @@ describe('workflow > form-trigge[r', () => { it('enabled / disabled', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', config: { collection: 'posts', }, @@ -97,7 +97,7 @@ describe('workflow > form-trigge[r', () => { it('only trigger if params provided matching collection config', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', config: { collection: 'posts', }, @@ -139,7 +139,7 @@ describe('workflow > form-trigge[r', () => { it('system fields could be accessed', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', config: { collection: 'posts', }, @@ -162,7 +162,7 @@ describe('workflow > form-trigge[r', () => { it('appends', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', config: { collection: 'posts', appends: ['createdBy'], @@ -186,7 +186,7 @@ describe('workflow > form-trigge[r', () => { it('user submitted form', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', config: { collection: 'posts', }, @@ -211,7 +211,7 @@ describe('workflow > form-trigge[r', () => { it('trigger after updated', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', config: { collection: 'posts', }, @@ -241,11 +241,50 @@ describe('workflow > form-trigge[r', () => { }); }); + describe.skip('destroy', () => { + it('trigger after destroyed', async () => { + const workflow = await WorkflowModel.create({ + enabled: true, + type: 'action', + config: { + collection: 'posts', + }, + }); + + const p1 = await PostRepo.create({ + values: { title: 't1' }, + }); + const p2 = await PostRepo.create({ + values: { title: 't2' }, + }); + const res1 = await userAgents[0].resource('posts').destroy({ + filterByTk: p1.id, + }); + expect(res1.status).toBe(200); + + await sleep(500); + + const e1 = await workflow.getExecutions(); + expect(e1.length).toBe(0); + + const res2 = await userAgents[0].resource('posts').destroy({ + filterByTk: p2.id, + triggerWorkflows: `${workflow.key}`, + }); + + await sleep(500); + + const [e2] = await workflow.getExecutions(); + expect(e2.status).toBe(EXECUTION_STATUS.RESOLVED); + expect(e2.context.data).toBe(1); + }); + }); + describe('directly trigger', () => { it('trigger data', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', }); const res1 = await userAgents[0].resource('workflows').trigger({ @@ -264,12 +303,12 @@ describe('workflow > form-trigge[r', () => { it('multi trigger', async () => { const w1 = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', }); const w2 = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', }); const res1 = await userAgents[0].resource('workflows').trigger({ @@ -292,7 +331,7 @@ describe('workflow > form-trigge[r', () => { it('user submitted form', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', config: { collection: 'posts', appends: ['createdBy'], @@ -318,7 +357,7 @@ describe('workflow > form-trigge[r', () => { it('level: 1', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', }); const res1 = await userAgents[0].resource('workflows').trigger({ @@ -337,7 +376,7 @@ describe('workflow > form-trigge[r', () => { it('level: 2', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', }); const res1 = await userAgents[0].resource('workflows').trigger({ @@ -358,7 +397,7 @@ describe('workflow > form-trigge[r', () => { it('revision', async () => { const w1 = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', }); const res1 = await userAgents[0].resource('workflows').trigger({ @@ -405,7 +444,7 @@ describe('workflow > form-trigge[r', () => { it('sync form trigger', async () => { const workflow = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', sync: true, config: { collection: 'posts', @@ -426,7 +465,7 @@ describe('workflow > form-trigge[r', () => { it('sync and async will all be triggered in one action', async () => { const w1 = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', config: { collection: 'posts', }, @@ -434,7 +473,7 @@ describe('workflow > form-trigge[r', () => { const w2 = await WorkflowModel.create({ enabled: true, - type: 'form', + type: 'action', sync: true, config: { collection: 'posts', diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/index.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/index.ts similarity index 100% rename from packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/index.ts rename to packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/index.ts diff --git a/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/migrations/20240227172623-change-name.ts b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/migrations/20240227172623-change-name.ts new file mode 100644 index 000000000..902184577 --- /dev/null +++ b/packages/plugins/@nocobase/plugin-workflow-action-trigger/src/server/migrations/20240227172623-change-name.ts @@ -0,0 +1,22 @@ +import { Migration } from '@nocobase/server'; + +export default class extends Migration { + appVersion = '<0.19.0-alpha.10'; + on = 'afterSync'; + async up() { + const { db } = this.context; + + const WorkflowRepo = db.getRepository('workflows'); + await db.sequelize.transaction(async (transaction) => { + await WorkflowRepo.update({ + filter: { + type: 'form', + }, + values: { + type: 'action', + }, + transaction, + }); + }); + } +} diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/package.json b/packages/plugins/@nocobase/plugin-workflow-form-trigger/package.json deleted file mode 100644 index 4be920aa1..000000000 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "@nocobase/plugin-workflow-form-trigger", - "displayName": "Workflow: Form trigger", - "displayName.zh-CN": "工作流:表单触发器", - "description": "Bind form buttons to trigger workflow events when submitting.", - "description.zh-CN": "可对表单按钮绑定,在提交时触发对应的工作流事件。", - "version": "0.20.0-alpha.5", - "license": "AGPL-3.0", - "main": "./dist/server/index.js", - "homepage": "https://docs.nocobase.com/handbook/workflow-form-trigger", - "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/workflow-form-trigger", - "devDependencies": { - "antd": "5.x", - "react": "18.x", - "react-i18next": "^11.15.1" - }, - "peerDependencies": { - "@nocobase/client": "0.x", - "@nocobase/database": "0.x", - "@nocobase/plugin-workflow": ">=0.17.0-alpha.3", - "@nocobase/server": "0.x", - "@nocobase/test": "0.x" - }, - "gitHead": "d0b4efe4be55f8c79a98a331d99d9f8cf99021a1", - "keywords": [ - "Workflow" - ] -} diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/index.ts b/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/index.ts deleted file mode 100644 index 87681352a..000000000 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Plugin } from '@nocobase/client'; -import WorkflowPlugin from '@nocobase/plugin-workflow/client'; - -import FormTrigger from './FormTrigger'; - -export default class extends Plugin { - async afterAdd() { - // await this.app.pm.add() - } - - async beforeLoad() {} - - // You can get and modify the app instance here - async load() { - const workflow = this.app.pm.get('workflow') as WorkflowPlugin; - workflow.registerTrigger('form', FormTrigger); - } -} diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/zh-CN.json b/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/zh-CN.json deleted file mode 100644 index 75efb97da..000000000 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/locale/zh-CN.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Form event": "表单事件", - "Event triggers when submitted a workflow bound form action.": "在提交绑定工作流的表单操作按钮后触发。", - "Form data model": "表单数据模型", - "Use a collection to match form data.": "使用一个数据表来匹配表单数据。", - "Associations to use": "待使用的关系数据", - "Trigger data": "触发器数据", - "User submitted form": "提交表单的用户", - "Role of user submitted form": "提交表单用户的角色" -} diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/Plugin.ts b/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/Plugin.ts deleted file mode 100644 index f84f35e9f..000000000 --- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/Plugin.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Plugin } from '@nocobase/server'; -import WorkflowPlugin from '@nocobase/plugin-workflow'; - -import FormTrigger from './FormTrigger'; - -export default class extends Plugin { - async load() { - const workflowPlugin = this.app.getPlugin(WorkflowPlugin); - workflowPlugin.triggers.register('form', new FormTrigger(workflowPlugin)); - } -} diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client/components/FormTriggerWorkflowActionInitializerV2.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client/components/FormTriggerWorkflowActionInitializerV2.tsx deleted file mode 100644 index f88b0a22b..000000000 --- a/packages/plugins/@nocobase/plugin-workflow/src/client/components/FormTriggerWorkflowActionInitializerV2.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import { BlockInitializer, useSchemaInitializerItem } from '@nocobase/client'; - -export const FormTriggerWorkflowActionInitializerV2 = () => { - const schema = { - title: '{{t("Submit to workflow", { ns: "workflow" })}}', - 'x-component': 'Action', - 'x-component-props': { - useProps: '{{ useTriggerWorkflowsActionProps }}', - }, - 'x-toolbar': 'ActionSchemaToolbar', - 'x-settings': 'actionSettings:submitToWorkflow', - 'x-action-settings': { - assignedValues: {}, - skipValidator: false, - onSuccess: { - manualClose: true, - redirecting: false, - successMessage: '{{t("Submitted successfully")}}', - }, - triggerWorkflows: [], - }, - 'x-action': 'customize:triggerWorkflows', - }; - - const itemConfig = useSchemaInitializerItem(); - return ; -}; diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client/components/index.ts b/packages/plugins/@nocobase/plugin-workflow/src/client/components/index.ts index 325a72fd0..bdcf67aa7 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/client/components/index.ts +++ b/packages/plugins/@nocobase/plugin-workflow/src/client/components/index.ts @@ -4,4 +4,3 @@ export * from './FilterDynamicComponent'; export * from './RadioWithTooltip'; export * from './CheckboxGroupWithTooltip'; export * from './ValueBlock'; -export * from './FormTriggerWorkflowActionInitializerV2'; diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client/hooks/useTriggerWorkflowActionProps.ts b/packages/plugins/@nocobase/plugin-workflow/src/client/hooks/useTriggerWorkflowActionProps.ts index 5849622fa..c6070dcc1 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/client/hooks/useTriggerWorkflowActionProps.ts +++ b/packages/plugins/@nocobase/plugin-workflow/src/client/hooks/useTriggerWorkflowActionProps.ts @@ -8,6 +8,7 @@ import { useBlockRequestContext, useCollectValuesToSubmit, useCompile, + useRecord, } from '@nocobase/client'; import { isURL } from '@nocobase/utils/client'; @@ -73,3 +74,58 @@ export function useTriggerWorkflowsActionProps() { }, }; } + +export function useRecordTriggerWorkflowsActionProps() { + const compile = useCompile(); + const api = useAPIClient(); + const record = useRecord(); + const actionField = useField(); + const actionSchema = useFieldSchema(); + const { field, __parent } = useBlockRequestContext(); + const { setVisible } = useActionContext(); + const { modal } = App.useApp(); + const navigate = useNavigate(); + const { onSuccess, triggerWorkflows } = actionSchema?.['x-action-settings'] ?? {}; + + return { + async onClick() { + actionField.data = field.data || {}; + actionField.data.loading = true; + + try { + await api.resource('workflows').trigger({ + values: record, + // TODO(refactor): should change to inject by plugin + triggerWorkflows: triggerWorkflows?.length + ? triggerWorkflows.map((row) => [row.workflowKey, row.context].filter(Boolean).join('!')).join(',') + : undefined, + }); + __parent?.service?.refresh?.(); + setVisible?.(false); + if (!onSuccess?.successMessage) { + return; + } + if (onSuccess?.manualClose) { + modal.success({ + title: compile(onSuccess?.successMessage), + async onOk() { + if (onSuccess?.redirecting && onSuccess?.redirectTo) { + if (isURL(onSuccess.redirectTo)) { + window.location.href = onSuccess.redirectTo; + } else { + navigate(onSuccess.redirectTo); + } + } + }, + }); + } else { + message.success(compile(onSuccess?.successMessage)); + } + } catch (error) { + console.error(error); + } finally { + actionField.data.loading = false; + } + }, + }; +} diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client/index.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client/index.tsx index 619f04cde..628bf0706 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/client/index.tsx +++ b/packages/plugins/@nocobase/plugin-workflow/src/client/index.tsx @@ -9,7 +9,7 @@ export * from './utils'; export * from './hooks/useGetAriaLabelOfAddButton'; export { default as useStyles } from './style'; export * from './variable'; -export { getCollectionFieldOptions, useWorkflowVariableOptions } from './variable'; +export * from './hooks/useTriggerWorkflowActionProps'; import React from 'react'; @@ -30,8 +30,6 @@ import QueryInstruction from './nodes/query'; import CreateInstruction from './nodes/create'; import UpdateInstruction from './nodes/update'; import DestroyInstruction from './nodes/destroy'; -import { useTriggerWorkflowsActionProps } from './hooks/useTriggerWorkflowActionProps'; -import { FormTriggerWorkflowActionInitializerV2 } from './components/FormTriggerWorkflowActionInitializerV2'; import { getWorkflowDetailPath, getWorkflowExecutionsPath } from './constant'; import { NAMESPACE } from './locale'; import { customizeSubmitToWorkflowActionSettings } from './settings/customizeSubmitToWorkflowActionSettings'; @@ -74,7 +72,6 @@ export default class PluginWorkflowClient extends Plugin { async load() { this.addRoutes(); - this.addScopes(); this.addComponents(); this.app.pluginSettingsManager.add(NAMESPACE, { @@ -99,17 +96,10 @@ export default class PluginWorkflowClient extends Plugin { this.registerInstruction('destroy', DestroyInstruction); } - addScopes() { - this.app.addScopes({ - useTriggerWorkflowsActionProps, - }); - } - addComponents() { this.app.addComponents({ WorkflowPage, ExecutionPage, - FormTriggerWorkflowActionInitializerV2, }); } diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/utils.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/utils.ts index 55fdabd43..aa41be557 100644 --- a/packages/plugins/@nocobase/plugin-workflow/src/server/utils.ts +++ b/packages/plugins/@nocobase/plugin-workflow/src/server/utils.ts @@ -1,6 +1,6 @@ import { Model } from '@nocobase/database'; -export function toJSON(data: Model | Model[]): object { +export function toJSON(data: any): any { if (Array.isArray(data)) { return data.map(toJSON); } diff --git a/packages/presets/nocobase/package.json b/packages/presets/nocobase/package.json index a8642dbcc..657f00a47 100644 --- a/packages/presets/nocobase/package.json +++ b/packages/presets/nocobase/package.json @@ -51,10 +51,10 @@ "@nocobase/plugin-users": "0.20.0-alpha.5", "@nocobase/plugin-verification": "0.20.0-alpha.5", "@nocobase/plugin-workflow": "0.20.0-alpha.5", + "@nocobase/plugin-workflow-action-trigger": "0.20.0-alpha.5", "@nocobase/plugin-workflow-aggregate": "0.20.0-alpha.5", "@nocobase/plugin-workflow-delay": "0.20.0-alpha.5", "@nocobase/plugin-workflow-dynamic-calculation": "0.20.0-alpha.5", - "@nocobase/plugin-workflow-form-trigger": "0.20.0-alpha.5", "@nocobase/plugin-workflow-loop": "0.20.0-alpha.5", "@nocobase/plugin-workflow-manual": "0.20.0-alpha.5", "@nocobase/plugin-workflow-parallel": "0.20.0-alpha.5", diff --git a/packages/presets/nocobase/src/server/index.ts b/packages/presets/nocobase/src/server/index.ts index 234009d46..8057908cc 100644 --- a/packages/presets/nocobase/src/server/index.ts +++ b/packages/presets/nocobase/src/server/index.ts @@ -16,10 +16,10 @@ export class PresetNocoBase extends Plugin { 'acl', 'china-region', 'workflow', + 'workflow-action-trigger', 'workflow-aggregate', 'workflow-delay', 'workflow-dynamic-calculation', - 'workflow-form-trigger', 'workflow-loop', 'workflow-manual', 'workflow-parallel', diff --git a/packages/presets/nocobase/src/server/migrations/20240227172623-change-name.ts b/packages/presets/nocobase/src/server/migrations/20240227172623-change-name.ts new file mode 100644 index 000000000..b537353de --- /dev/null +++ b/packages/presets/nocobase/src/server/migrations/20240227172623-change-name.ts @@ -0,0 +1,14 @@ +import { Migration } from '@nocobase/server'; + +export default class extends Migration { + on = 'beforeLoad'; // 'beforeLoad' or 'afterLoad' + appVersion = '<0.19.0-alpha.10'; + + async up() { + await this.pm.repository.destroy({ + filter: { + packageName: '@nocobase/plugin-workflow-form-trigger', + }, + }); + } +}