= SelectProps & {
targetField?: any;
service: ResourceActionOptions
;
CustomDropdownRender?: (v: any) => any;
+ optionFilter?: (option: any) => boolean;
};
const InternalRemoteSelect = connect(
@@ -37,6 +38,7 @@ const InternalRemoteSelect = connect(
mapOptions,
targetField: _targetField,
CustomDropdownRender,
+ optionFilter,
...others
} = props;
const [open, setOpen] = useState(false);
@@ -192,8 +194,9 @@ const InternalRemoteSelect = connect(
}
const valueOptions =
(v != null && (Array.isArray(v) ? v : [{ ...v, [fieldNames.value]: v[fieldNames.value] || v }])) || [];
- return uniqBy(data?.data?.concat(valueOptions ?? []), fieldNames.value);
- }, [value, defaultValue, data?.data, fieldNames.value]);
+ const filtered = typeof optionFilter === 'function' ? data.data.filter(optionFilter) : data.data;
+ return uniqBy(filtered.concat(valueOptions ?? []), fieldNames.value);
+ }, [value, defaultValue, data?.data, fieldNames.value, optionFilter]);
const onDropdownVisibleChange = (visible) => {
setOpen(visible);
searchData.current = null;
diff --git a/packages/core/client/src/schema-initializer/items/BulkDestroyActionInitializer.tsx b/packages/core/client/src/schema-initializer/items/BulkDestroyActionInitializer.tsx
index f3faab157..c8a3245e2 100644
--- a/packages/core/client/src/schema-initializer/items/BulkDestroyActionInitializer.tsx
+++ b/packages/core/client/src/schema-initializer/items/BulkDestroyActionInitializer.tsx
@@ -22,6 +22,9 @@ export const BulkDestroyActionInitializer = (props) => {
},
useProps: '{{ useBulkDestroyActionProps }}',
},
+ 'x-action-settings': {
+ triggerWorkflows: [],
+ },
};
if (collection) {
schema['x-acl-action'] = `${collection.name}:destroy`;
diff --git a/packages/core/client/src/schema-initializer/items/DestroyActionInitializer.tsx b/packages/core/client/src/schema-initializer/items/DestroyActionInitializer.tsx
index e43d1fa3e..6afcd0566 100644
--- a/packages/core/client/src/schema-initializer/items/DestroyActionInitializer.tsx
+++ b/packages/core/client/src/schema-initializer/items/DestroyActionInitializer.tsx
@@ -16,6 +16,9 @@ export const DestroyActionInitializer = (props) => {
},
useProps: '{{ useDestroyActionProps }}',
},
+ 'x-action-settings': {
+ triggerWorkflows: [],
+ },
};
return ;
};
diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/FormTrigger.tsx b/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/FormTrigger.tsx
index fd1ba08bd..551a3a691 100644
--- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/FormTrigger.tsx
+++ b/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/FormTrigger.tsx
@@ -59,7 +59,7 @@ export default class extends Trigger {
scope = {
useCollectionDataSource,
};
- useActionTriggerable = true;
+ isActionTriggerable = true;
useVariables(config, options) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const compile = useCompile();
diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/configuration.test.ts b/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/configuration.test.ts
index 8ea0ae543..33721f737 100644
--- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/configuration.test.ts
+++ b/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/client/__e2e__/configuration.test.ts
@@ -93,7 +93,7 @@ test.describe('Configuration page to configure the Trigger node', () => {
await page.getByRole('button', { name: 'plus Add workflow' }).click();
await page.getByRole('button', { name: 'Select workflow' }).click();
await page.getByRole('option', { name: workFlowName }).click();
- await page.getByRole('button', { name: 'OK', exact: true }).click();
+ await page.getByRole('button', { name: 'Submit', exact: true }).click();
// 2、测试步骤:进入“数据区块”-“添加”按钮,填写表单,点击“确定”按钮
const fieldData = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
@@ -187,7 +187,7 @@ test.describe('Configuration page to configure the Trigger node', () => {
await page.getByRole('button', { name: 'plus Add workflow' }).click();
await page.getByRole('button', { name: 'Select workflow' }).click();
await page.getByRole('option', { name: workFlowName }).click();
- await page.getByRole('button', { name: 'OK', exact: true }).click();
+ await page.getByRole('button', { name: 'Submit', exact: true }).click();
// 2、测试步骤:进入“数据区块”-“添加”按钮,填写表单,点击“确定”按钮
const fieldData = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
diff --git a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/FormTrigger.ts b/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/FormTrigger.ts
index a55f5ac31..07acc6041 100644
--- a/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/FormTrigger.ts
+++ b/packages/plugins/@nocobase/plugin-workflow-form-trigger/src/server/FormTrigger.ts
@@ -116,14 +116,7 @@ export default class extends Trigger {
}
for (const event of syncGroup) {
- await this.workflow.trigger(event[0], event[1]);
- // if (processor.execution.status < EXECUTION_STATUS.STARTED) {
- // // error handling
- // return context.throw(
- // 500,
- // 'Your data saved, but some workflow on your action failed, please contact the administrator.',
- // );
- // }
+ await this.workflow.trigger(event[0], event[1], { httpContext: context });
}
for (const event of asyncGroup) {
diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client/components/CheckboxGroupWithTooltip.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client/components/CheckboxGroupWithTooltip.tsx
new file mode 100644
index 000000000..32af5ee7f
--- /dev/null
+++ b/packages/plugins/@nocobase/plugin-workflow/src/client/components/CheckboxGroupWithTooltip.tsx
@@ -0,0 +1,40 @@
+import { QuestionCircleOutlined } from '@ant-design/icons';
+import { css, useCompile } from '@nocobase/client';
+import { Checkbox, Space, Tooltip } from 'antd';
+import React from 'react';
+
+export interface CheckboxGroupWithTooltipOption {
+ value: any;
+ label: string;
+ tooltip?: string;
+}
+
+export function CheckboxGroupWithTooltip(props) {
+ const { options = [], direction, ...other } = props;
+ const compile = useCompile();
+
+ return (
+
+
+ {options.map((option) => (
+
+
+ {compile(option.label)}
+
+ {option.tooltip && (
+
+
+
+ )}
+
+ ))}
+
+
+ );
+}
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 3190699da..bdcf67aa7 100644
--- a/packages/plugins/@nocobase/plugin-workflow/src/client/components/index.ts
+++ b/packages/plugins/@nocobase/plugin-workflow/src/client/components/index.ts
@@ -2,4 +2,5 @@ export * from './CollectionBlockInitializer';
export * from './FieldsSelect';
export * from './FilterDynamicComponent';
export * from './RadioWithTooltip';
+export * from './CheckboxGroupWithTooltip';
export * from './ValueBlock';
diff --git a/packages/plugins/@nocobase/plugin-workflow/src/client/triggers/index.tsx b/packages/plugins/@nocobase/plugin-workflow/src/client/triggers/index.tsx
index ec9e7d171..5149f6d0f 100644
--- a/packages/plugins/@nocobase/plugin-workflow/src/client/triggers/index.tsx
+++ b/packages/plugins/@nocobase/plugin-workflow/src/client/triggers/index.tsx
@@ -65,7 +65,7 @@ export abstract class Trigger {
components?: { [key: string]: any };
useInitializers?(config): SchemaInitializerItemType | null;
initializers?: any;
- useActionTriggerable?: boolean | (() => boolean);
+ isActionTriggerable?: boolean | ((config: object, context?: object) => boolean);
}
function TriggerExecution() {
diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/Plugin.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/Plugin.ts
index dfdf3726d..fd62c35a9 100644
--- a/packages/plugins/@nocobase/plugin-workflow/src/server/Plugin.ts
+++ b/packages/plugins/@nocobase/plugin-workflow/src/server/Plugin.ts
@@ -190,6 +190,7 @@ export default class PluginWorkflowServer extends Plugin {
'workflows.nodes:*',
'executions:list',
'executions:get',
+ 'executions:cancel',
'flow_nodes:update',
'flow_nodes:destroy',
],
@@ -239,8 +240,8 @@ export default class PluginWorkflowServer extends Plugin {
});
this.app.on('beforeStop', async () => {
- const collection = db.getCollection('workflows');
- const workflows = await collection.repository.find({
+ const repository = db.getRepository('workflows');
+ const workflows = await repository.find({
filter: { enabled: true },
});
@@ -280,7 +281,7 @@ export default class PluginWorkflowServer extends Plugin {
public trigger(
workflow: WorkflowModel,
context: object,
- options: { context?: any } & Transactionable = {},
+ options: { [key: string]: any } & Transactionable = {},
): void | Promise {
const logger = this.getLogger(workflow.id);
if (!this.ready) {
@@ -298,7 +299,8 @@ export default class PluginWorkflowServer extends Plugin {
return this.triggerSync(workflow, context, options);
}
- this.events.push([workflow, context, { context: options.context }]);
+ const { transaction, ...rest } = options;
+ this.events.push([workflow, context, rest]);
this.eventsCount = this.events.length;
logger.info(`new event triggered, now events: ${this.events.length}`);
@@ -317,7 +319,7 @@ export default class PluginWorkflowServer extends Plugin {
private async triggerSync(
workflow: WorkflowModel,
context: object,
- options: { context?: any } & Transactionable = {},
+ options: { [key: string]: any } & Transactionable = {},
): Promise {
let execution;
try {
diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/Processor.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/Processor.ts
index aa60555f7..798dce40c 100644
--- a/packages/plugins/@nocobase/plugin-workflow/src/server/Processor.ts
+++ b/packages/plugins/@nocobase/plugin-workflow/src/server/Processor.ts
@@ -9,6 +9,7 @@ import type { ExecutionModel, FlowNodeModel, JobModel } from './types';
export interface ProcessorOptions extends Transactionable {
plugin: Plugin;
+ [key: string]: any;
}
export default class Processor {
diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/instructions/CreateInstruction.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/instructions/CreateInstruction.ts
index d8f1790aa..9095032d3 100644
--- a/packages/plugins/@nocobase/plugin-workflow/src/server/instructions/CreateInstruction.ts
+++ b/packages/plugins/@nocobase/plugin-workflow/src/server/instructions/CreateInstruction.ts
@@ -10,6 +10,7 @@ export class CreateInstruction extends Instruction {
const { repository, model } = (node.constructor).database.getCollection(collection);
const options = processor.getParsedValue(params, node.id);
+
const created = await repository.create({
...options,
context: {
diff --git a/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/CollectionTrigger.ts b/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/CollectionTrigger.ts
index abe6de525..eb5f5b7ce 100644
--- a/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/CollectionTrigger.ts
+++ b/packages/plugins/@nocobase/plugin-workflow/src/server/triggers/CollectionTrigger.ts
@@ -88,20 +88,13 @@ async function handler(this: CollectionTrigger, workflow: WorkflowModel, data: M
if (workflow.sync) {
await this.workflow.trigger(
workflow,
- { data: json },
+ { data: json, stack: context?.stack },
{
- context,
transaction,
},
);
} else {
- this.workflow.trigger(
- workflow,
- { data: json },
- {
- context,
- },
- );
+ this.workflow.trigger(workflow, { data: json, stack: context?.stack });
}
}
@@ -155,15 +148,11 @@ export default class CollectionTrigger extends Trigger {
}
}
- async validateEvent(
- workflow: WorkflowModel,
- context: any,
- options: { context?: { stack?: number[] } } & Transactionable,
- ): Promise {
- if (options.context?.stack) {
+ async validateEvent(workflow: WorkflowModel, context: any, options: Transactionable): Promise {
+ if (context.stack) {
const existed = await workflow.countExecutions({
where: {
- id: options.context.stack,
+ id: context.stack,
},
transaction: options.transaction,
});
@@ -172,13 +161,11 @@ export default class CollectionTrigger extends Trigger {
this.workflow
.getLogger(workflow.id)
.warn(
- `workflow ${workflow.id} has already been triggered in stack executions (${options.context.stack}), and newly triggering will be skipped.`,
+ `workflow ${workflow.id} has already been triggered in stack executions (${context.stack}), and newly triggering will be skipped.`,
);
return false;
}
-
- context.stack = options.context.stack;
}
return true;