feat(plugin-workflow): add clear button for clearing executions (#2401)
This commit is contained in:
parent
d693aad89b
commit
e5f5787175
@ -1,9 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ISchema } from '@formily/react';
|
import { ISchema } from '@formily/react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { useActionContext } from '@nocobase/client';
|
import { useActionContext, useRecord, useResourceActionContext, useResourceContext } from '@nocobase/client';
|
||||||
import { ExecutionStatusOptions } from '../constants';
|
import { ExecutionStatusOptions } from '../constants';
|
||||||
import { NAMESPACE } from '../locale';
|
import { NAMESPACE } from '../locale';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { message } from 'antd';
|
||||||
|
|
||||||
export const executionCollection = {
|
export const executionCollection = {
|
||||||
name: 'executions',
|
name: 'executions',
|
||||||
@ -87,10 +89,31 @@ export const executionSchema = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
// filter: {
|
clear: {
|
||||||
// type: 'object',
|
type: 'void',
|
||||||
// 'x-component': 'Filter',
|
title: '{{t("Clear")}}',
|
||||||
// }
|
'x-component': 'Action',
|
||||||
|
'x-component-props': {
|
||||||
|
useAction() {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { refresh, defaultRequest } = useResourceActionContext();
|
||||||
|
const { resource } = useResourceContext();
|
||||||
|
const { setVisible } = useActionContext();
|
||||||
|
return {
|
||||||
|
async run() {
|
||||||
|
await resource.destroy({ filter: defaultRequest.params?.filter });
|
||||||
|
message.success(t('Operation succeeded'));
|
||||||
|
refresh();
|
||||||
|
setVisible(false);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
confirm: {
|
||||||
|
title: `{{t("Clear all executions", { ns: "${NAMESPACE}" })}}`,
|
||||||
|
content: `{{t("Clear executions will not reset executed count, and started executions will not be deleted, are you sure you want to delete them all?", { ns: "${NAMESPACE}" })}}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
table: {
|
table: {
|
||||||
@ -152,7 +175,7 @@ export const executionSchema = {
|
|||||||
split: '|',
|
split: '|',
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
config: {
|
link: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: `{{t("Details", { ns: "${NAMESPACE}" })}}`,
|
title: `{{t("Details", { ns: "${NAMESPACE}" })}}`,
|
||||||
'x-component': 'ExecutionLink',
|
'x-component': 'ExecutionLink',
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
export default {
|
export default {
|
||||||
Workflow: '工作流',
|
Workflow: '工作流',
|
||||||
'Execution history': '执行历史',
|
'Execution history': '执行历史',
|
||||||
|
'Clear all executions': '清除所有执行记录',
|
||||||
|
'Clear executions will not reset executed count, and started executions will not be deleted, are you sure you want to delete them all?':
|
||||||
|
'清空执行记录不会重置执行次数,且执行中的也不会被删除,确定要删除所有执行记录吗?',
|
||||||
Executed: '已执行',
|
Executed: '已执行',
|
||||||
Reload: '重载',
|
Reload: '重载',
|
||||||
'Trigger type': '触发方式',
|
'Trigger type': '触发方式',
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
import { MockServer } from '@nocobase/test';
|
||||||
|
import Database from '@nocobase/database';
|
||||||
|
import { getApp, sleep } from '..';
|
||||||
|
import { EXECUTION_STATUS } from '../../constants';
|
||||||
|
|
||||||
|
describe('workflow > actions > executions', () => {
|
||||||
|
let app: MockServer;
|
||||||
|
let agent;
|
||||||
|
let db: Database;
|
||||||
|
let PostRepo;
|
||||||
|
let WorkflowModel;
|
||||||
|
let workflow;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
app = await getApp();
|
||||||
|
agent = app.agent();
|
||||||
|
db = app.db;
|
||||||
|
WorkflowModel = db.getCollection('workflows').model;
|
||||||
|
PostRepo = db.getCollection('posts').repository;
|
||||||
|
|
||||||
|
workflow = await WorkflowModel.create({
|
||||||
|
enabled: true,
|
||||||
|
type: 'collection',
|
||||||
|
config: {
|
||||||
|
mode: 1,
|
||||||
|
collection: 'posts',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => await app.destroy());
|
||||||
|
|
||||||
|
describe('destroy', () => {
|
||||||
|
it('completed execution could be deleted', async () => {
|
||||||
|
const post = await PostRepo.create({ values: { title: 't1' } });
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const e1 = await workflow.getExecutions();
|
||||||
|
expect(e1.length).toBe(1);
|
||||||
|
expect(e1[0].get('status')).toBe(EXECUTION_STATUS.RESOLVED);
|
||||||
|
|
||||||
|
await agent.resource('executions').destroy({
|
||||||
|
filter: {
|
||||||
|
key: workflow.key,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const e2 = await workflow.getExecutions();
|
||||||
|
expect(e2.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('started execution could not be deleted', async () => {
|
||||||
|
await workflow.createNode({
|
||||||
|
type: 'pending',
|
||||||
|
});
|
||||||
|
|
||||||
|
const post = await PostRepo.create({ values: { title: 't1' } });
|
||||||
|
await sleep(500);
|
||||||
|
|
||||||
|
const e1 = await workflow.getExecutions();
|
||||||
|
expect(e1.length).toBe(1);
|
||||||
|
expect(e1[0].get('status')).toBe(EXECUTION_STATUS.STARTED);
|
||||||
|
|
||||||
|
await agent.resource('executions').destroy({
|
||||||
|
filter: {
|
||||||
|
key: workflow.key,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const e2 = await workflow.getExecutions();
|
||||||
|
expect(e2.length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -37,6 +37,14 @@ export async function getApp({ manual, ...options }: MockAppOptions = {}): Promi
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
pending: {
|
||||||
|
run(node, input, processor) {
|
||||||
|
return {
|
||||||
|
status: JOB_STATUS.PENDING,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
'prompt->error': {
|
'prompt->error': {
|
||||||
run(node, input, processor) {
|
run(node, input, processor) {
|
||||||
return {
|
return {
|
||||||
|
15
packages/plugins/workflow/src/server/actions/executions.ts
Normal file
15
packages/plugins/workflow/src/server/actions/executions.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import actions, { Context } from '@nocobase/actions';
|
||||||
|
import { Op } from '@nocobase/database';
|
||||||
|
import { EXECUTION_STATUS } from '../constants';
|
||||||
|
|
||||||
|
export async function destroy(context: Context, next) {
|
||||||
|
context.action.mergeParams({
|
||||||
|
filter: {
|
||||||
|
status: {
|
||||||
|
[Op.ne]: EXECUTION_STATUS.STARTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await actions.destroy(context, next);
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import * as workflows from './workflows';
|
import * as workflows from './workflows';
|
||||||
import * as nodes from './nodes';
|
import * as nodes from './nodes';
|
||||||
|
import * as executions from './executions';
|
||||||
|
|
||||||
function make(name, mod) {
|
function make(name, mod) {
|
||||||
return Object.keys(mod).reduce(
|
return Object.keys(mod).reduce(
|
||||||
@ -21,5 +22,6 @@ export default function ({ app }) {
|
|||||||
...make('flow_nodes', {
|
...make('flow_nodes', {
|
||||||
update: nodes.update,
|
update: nodes.update,
|
||||||
}),
|
}),
|
||||||
|
...make('executions', executions),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user