fix(workflow): 添加提交按钮允许绑定通用工作流并触发 (#1560)
Reviewed-on: daoyoucloud/tachybase#1560 Reviewed-by: sealday <zhanglin@daoyoucloud.com> Co-authored-by: bai.zixv <bai.zixv@foxmail.com> Co-committed-by: bai.zixv <bai.zixv@foxmail.com>
This commit is contained in:
parent
eff5bc3890
commit
569dbf2423
@ -55,8 +55,11 @@ export class OmniActionTrigger extends Trigger {
|
|||||||
};
|
};
|
||||||
scope = { useCollectionDataSource };
|
scope = { useCollectionDataSource };
|
||||||
components = {};
|
components = {};
|
||||||
isActionTriggerable = (config, context) => {
|
isActionTriggerable = (config, context: any = {}) => {
|
||||||
return context.buttonAction === 'customize:triggerWorkflows';
|
const { buttonAction } = context;
|
||||||
|
const conditionList = [buttonAction === 'customize:triggerWorkflows', buttonAction === 'submit'];
|
||||||
|
const isAvailable = conditionList.some((val) => val === true);
|
||||||
|
return isAvailable;
|
||||||
};
|
};
|
||||||
useVariables(config: Record<string, any>, options?: UseVariableOptions) {
|
useVariables(config: Record<string, any>, options?: UseVariableOptions) {
|
||||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import { Context, Next } from '@tachybase/actions';
|
||||||
import { joinCollectionName, parseCollectionName } from '@tachybase/data-source-manager';
|
import { joinCollectionName, parseCollectionName } from '@tachybase/data-source-manager';
|
||||||
|
import { Model, modelAssociationByKey } from '@tachybase/database';
|
||||||
import PluginErrorHandler from '@tachybase/plugin-error-handler';
|
import PluginErrorHandler from '@tachybase/plugin-error-handler';
|
||||||
|
|
||||||
import _, { isArray } from 'lodash';
|
import _, { get, isArray } from 'lodash';
|
||||||
|
|
||||||
import { EXECUTION_STATUS } from '../../constants';
|
import { EXECUTION_STATUS } from '../../constants';
|
||||||
import Trigger from '../../triggers';
|
import Trigger from '../../triggers';
|
||||||
@ -17,6 +19,21 @@ class CustomActionInterceptionError extends Error {
|
|||||||
}
|
}
|
||||||
export class OmniTrigger extends Trigger {
|
export class OmniTrigger extends Trigger {
|
||||||
static TYPE = 'general-action';
|
static TYPE = 'general-action';
|
||||||
|
constructor(workflow) {
|
||||||
|
super(workflow);
|
||||||
|
this.workflow.app.resourcer.registerActionHandler('trigger', this.triggerAction);
|
||||||
|
this.workflow.app.acl.allow('*', 'trigger', 'loggedIn');
|
||||||
|
(this.workflow.app.pm.get(PluginErrorHandler) as PluginErrorHandler).errorHandler.register(
|
||||||
|
(err) => err instanceof CustomActionInterceptionError,
|
||||||
|
async (err, ctx) => {
|
||||||
|
ctx.body = {
|
||||||
|
errors: err.messages,
|
||||||
|
};
|
||||||
|
ctx.status = err.status;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
workflow.app.use(this.middleware, { after: 'dataSource' });
|
||||||
|
}
|
||||||
triggerAction = async (context, next) => {
|
triggerAction = async (context, next) => {
|
||||||
const {
|
const {
|
||||||
params: { filterByTk, values, triggerWorkflows = '', filter, resourceName, actionName },
|
params: { filterByTk, values, triggerWorkflows = '', filter, resourceName, actionName },
|
||||||
@ -123,20 +140,127 @@ export class OmniTrigger extends Trigger {
|
|||||||
}
|
}
|
||||||
await next();
|
await next();
|
||||||
};
|
};
|
||||||
constructor(workflow) {
|
|
||||||
super(workflow);
|
middleware = async (context: Context, next: Next) => {
|
||||||
this.workflow.app.resourcer.registerActionHandler('trigger', this.triggerAction);
|
const {
|
||||||
this.workflow.app.acl.allow('*', 'trigger', 'loggedIn');
|
resourceName,
|
||||||
(this.workflow.app.pm.get(PluginErrorHandler) as PluginErrorHandler).errorHandler.register(
|
actionName,
|
||||||
(err) => err instanceof CustomActionInterceptionError,
|
params: { triggerWorkflows },
|
||||||
async (err, ctx) => {
|
} = context.action;
|
||||||
ctx.body = {
|
|
||||||
errors: err.messages,
|
if (resourceName === 'workflows' && actionName === 'trigger') {
|
||||||
};
|
return this.triggerAction(context, next);
|
||||||
ctx.status = err.status;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await next();
|
||||||
|
|
||||||
|
if (!triggerWorkflows) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!['create', 'update'].includes(actionName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.trigger(context);
|
||||||
|
};
|
||||||
|
|
||||||
|
private async trigger(context: Context) {
|
||||||
|
const { triggerWorkflows = '', values } = context.action.params;
|
||||||
|
const dataSourceHeader = context.get('x-data-source') || 'main';
|
||||||
|
|
||||||
|
const { currentUser, currentRole } = context.state;
|
||||||
|
const { model: UserModel } = this.workflow.db.getCollection('users');
|
||||||
|
const userInfo = {
|
||||||
|
user: UserModel.build(currentUser).desensitize(),
|
||||||
|
roleName: currentRole,
|
||||||
|
};
|
||||||
|
|
||||||
|
const triggers = triggerWorkflows.split(',').map((trigger) => trigger.split('!'));
|
||||||
|
const workflowRepo = this.workflow.db.getRepository('workflows');
|
||||||
|
const workflows = (
|
||||||
|
await workflowRepo.find({
|
||||||
|
filter: {
|
||||||
|
key: triggers.map((trigger) => trigger[0]),
|
||||||
|
current: true,
|
||||||
|
type: 'general-action',
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).filter((workflow) => Boolean(workflow.config.collection));
|
||||||
|
const syncGroup = [];
|
||||||
|
const asyncGroup = [];
|
||||||
|
for (const workflow of workflows) {
|
||||||
|
const { collection, appends = [] } = workflow.config;
|
||||||
|
const [dataSourceName, collectionName] = parseCollectionName(collection);
|
||||||
|
const trigger = triggers.find((trigger) => trigger[0] == workflow.key);
|
||||||
|
const event = [workflow];
|
||||||
|
if (context.action.resourceName !== 'workflows') {
|
||||||
|
if (!context.body) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (dataSourceName !== dataSourceHeader) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const { body: data } = context;
|
||||||
|
for (const row of Array.isArray(data) ? data : [data]) {
|
||||||
|
let payload = row;
|
||||||
|
if (trigger[1]) {
|
||||||
|
const paths = trigger[1].split('.');
|
||||||
|
for (const field of paths) {
|
||||||
|
if (payload.get(field)) {
|
||||||
|
payload = payload.get(field);
|
||||||
|
} else {
|
||||||
|
const association: any = modelAssociationByKey(payload, field);
|
||||||
|
payload = await payload[association.accessors.get]();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const model = payload.constructor;
|
||||||
|
if (payload instanceof Model) {
|
||||||
|
if (collectionName !== 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 });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const { model, repository } = (<any>context.app).dataSourceManager.dataSources
|
||||||
|
.get(dataSourceName)
|
||||||
|
.collectionManager.getCollection(collectionName);
|
||||||
|
let data = trigger[1] ? get(values, trigger[1]) : values;
|
||||||
|
const pk = get(data, model.primaryKeyAttribute);
|
||||||
|
if (appends.length && pk != null) {
|
||||||
|
data = await repository.findOne({
|
||||||
|
filterByTk: pk,
|
||||||
|
appends,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// this.workflow.trigger(workflow, {
|
||||||
|
// data,
|
||||||
|
// ...userInfo,
|
||||||
|
// });
|
||||||
|
event.push({ data, ...userInfo });
|
||||||
|
}
|
||||||
|
(workflow.sync ? syncGroup : asyncGroup).push(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const event of syncGroup) {
|
||||||
|
await this.workflow.trigger(event[0], event[1], { httpContext: context });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const event of asyncGroup) {
|
||||||
|
this.workflow.trigger(event[0], event[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
on() {}
|
on() {}
|
||||||
off() {}
|
off() {}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user