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
This commit is contained in:
parent
d3627c5ba9
commit
c2b121cda6
@ -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,
|
||||
});
|
||||
|
||||
|
@ -19,6 +19,7 @@ export const UpdateRecordActionInitializer = (props) => {
|
||||
redirecting: false,
|
||||
successMessage: '{{t("Updated successfully")}}',
|
||||
},
|
||||
triggerWorkflows: [],
|
||||
},
|
||||
'x-component-props': {
|
||||
useProps: '{{ useCustomizeUpdateActionProps }}',
|
||||
|
@ -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,
|
||||
|
@ -37,5 +37,15 @@ export const detailsActionInitializers = new SchemaInitializer({
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'divider',
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
type: 'subMenu',
|
||||
name: 'customize',
|
||||
title: '{{t("Customize")}}',
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -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")}}',
|
||||
|
@ -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")}}',
|
||||
|
@ -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',
|
||||
|
@ -139,6 +139,7 @@ export const CalendarFormActionInitializers: SchemaInitializer = new SchemaIniti
|
||||
redirecting: false,
|
||||
successMessage: generateNTemplate('Updated successfully'),
|
||||
},
|
||||
triggerWorkflows: [],
|
||||
},
|
||||
'x-component-props': {
|
||||
useProps: '{{ useCustomizeUpdateActionProps }}',
|
||||
|
@ -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"
|
||||
]
|
||||
}
|
@ -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,
|
@ -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);
|
@ -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);
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
@ -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": "提交操作用户的角色"
|
||||
}
|
@ -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 = <typeof 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 });
|
@ -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));
|
||||
}
|
||||
}
|
@ -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',
|
@ -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,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -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"
|
||||
]
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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": "提交表单用户的角色"
|
||||
}
|
@ -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);
|
||||
workflowPlugin.triggers.register('form', new FormTrigger(workflowPlugin));
|
||||
}
|
||||
}
|
@ -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 <BlockInitializer {...itemConfig} schema={schema} item={itemConfig} />;
|
||||
};
|
@ -4,4 +4,3 @@ export * from './FilterDynamicComponent';
|
||||
export * from './RadioWithTooltip';
|
||||
export * from './CheckboxGroupWithTooltip';
|
||||
export * from './ValueBlock';
|
||||
export * from './FormTriggerWorkflowActionInitializerV2';
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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',
|
||||
|
@ -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',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user