Fix(plugin workflow): UX issues (#329)
* fix(plugin-workflow): typo * fix(plugin-workflow): text and style * fix(plugin-workflow): fix trigger form validation * fix(plugin-workflow): try to fix config field * fix: config * fix(plugin-workflow): node config value Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
72d32be2b0
commit
2e80e0c2c2
@ -32,7 +32,7 @@ export const calculators = [
|
||||
children: [
|
||||
{ value: 'add', name: '+' },
|
||||
{ value: 'minus', name: '-' },
|
||||
{ value: 'multipe', name: '*' },
|
||||
{ value: 'multiple', name: '*' },
|
||||
{ value: 'divide', name: '/' },
|
||||
{ value: 'mod', name: '%' },
|
||||
]
|
||||
@ -396,7 +396,10 @@ export const CollectionFieldset = observer(({ value, onChange, useProps }: any)
|
||||
`}>
|
||||
{fields.length
|
||||
? fields
|
||||
.filter(field => !field.hidden)
|
||||
.filter(field => (
|
||||
!field.hidden
|
||||
&& (field.uiSchema ? !field.uiSchema['x-read-pretty'] : true)
|
||||
))
|
||||
.map(field => {
|
||||
const operand = typeof value[field.name] === 'string'
|
||||
? parseStringValue(value[field.name], VTypes)
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React from 'react';
|
||||
import { Calculation } from '../calculators';
|
||||
|
||||
@ -6,10 +7,10 @@ export default {
|
||||
type: 'calculation',
|
||||
group: 'control',
|
||||
fieldset: {
|
||||
calculation: {
|
||||
'config.calculation': {
|
||||
type: 'object',
|
||||
title: '配置计算',
|
||||
name: 'calculation',
|
||||
name: 'config.calculation',
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'CalculationConfig',
|
||||
@ -26,6 +27,6 @@ export default {
|
||||
}
|
||||
},
|
||||
getter() {
|
||||
return <div>计算值</div>;
|
||||
return <div className={css`flex-shrink: 0`}>计算值</div>;
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import { css, cx } from "@emotion/css";
|
||||
import { Button, Select } from "antd";
|
||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||
import { Button, Select, Tooltip } from "antd";
|
||||
import { CloseCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import { Trans } from "react-i18next";
|
||||
|
||||
import { NodeDefaultView } from ".";
|
||||
@ -66,17 +66,20 @@ function CalculationGroup({ value, onChange }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={css`
|
||||
<div className={cx('node-type-condition-group', css`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: .5em 1em;
|
||||
border: 1px dashed #ddd;
|
||||
|
||||
.node-type-condition-group{
|
||||
padding: .5em 1em;
|
||||
border: 1px dashed #ddd;
|
||||
}
|
||||
|
||||
+ button{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
`}>
|
||||
`)}>
|
||||
<div className={css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -131,9 +134,9 @@ export default {
|
||||
type: 'condition',
|
||||
group: 'control',
|
||||
fieldset: {
|
||||
rejectOnFalse: {
|
||||
'config.rejectOnFalse': {
|
||||
type: 'boolean',
|
||||
name: 'rejectOnFalse',
|
||||
name: 'config.rejectOnFalse',
|
||||
title: '模式',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Radio.Group',
|
||||
@ -141,13 +144,33 @@ export default {
|
||||
disabled: true,
|
||||
},
|
||||
enum: [
|
||||
{ value: true, label: '通行模式' },
|
||||
{ value: false, label: '分支模式' },
|
||||
{
|
||||
value: true,
|
||||
label: (
|
||||
<Tooltip
|
||||
title="判断为“是”时继续"
|
||||
placement="bottom"
|
||||
>
|
||||
通行模式 <QuestionCircleOutlined style={{ color: '#999' }} />
|
||||
</Tooltip>
|
||||
)
|
||||
},
|
||||
{
|
||||
value: false,
|
||||
label: (
|
||||
<Tooltip
|
||||
title="判断结果分为“是”和“否”两个分支,分别继续"
|
||||
placement="bottom"
|
||||
>
|
||||
分支模式 <QuestionCircleOutlined style={{ color: '#999' }} />
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
],
|
||||
},
|
||||
calculation: {
|
||||
'config.calculation': {
|
||||
type: 'string',
|
||||
name: 'calculation',
|
||||
name: 'config.calculation',
|
||||
title: '条件配置',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'CalculationConfig',
|
||||
|
@ -1,17 +1,20 @@
|
||||
import React from 'react';
|
||||
import { Select } from 'antd';
|
||||
|
||||
import React from 'react';
|
||||
import { useCollectionDataSource, useCollectionManager, useCompile } from '../..';
|
||||
import { useFlowContext } from '../WorkflowCanvas';
|
||||
import { collection, values } from '../schemas/collection';
|
||||
import { BaseTypeSet, CollectionFieldset } from '../calculators';
|
||||
import { collection, values } from '../schemas/collection';
|
||||
import { useFlowContext } from '../WorkflowCanvas';
|
||||
|
||||
|
||||
export default {
|
||||
title: '新增数据',
|
||||
type: 'create',
|
||||
group: 'model',
|
||||
fieldset: {
|
||||
collection,
|
||||
'config.collection': {
|
||||
name: 'config.collection',
|
||||
...collection,
|
||||
},
|
||||
// multiple: {
|
||||
// type: 'boolean',
|
||||
// title: '多条数据',
|
||||
@ -22,9 +25,9 @@ export default {
|
||||
// disabled: true
|
||||
// }
|
||||
// },
|
||||
params: {
|
||||
'config.params': {
|
||||
type: 'object',
|
||||
name: 'params',
|
||||
name: 'config.params',
|
||||
title: '',
|
||||
'x-decorator': 'FormItem',
|
||||
properties: {
|
||||
|
@ -8,10 +8,10 @@ export default {
|
||||
type: 'destroy',
|
||||
group: 'model',
|
||||
fieldset: {
|
||||
collection,
|
||||
params: {
|
||||
'config.collection': collection,
|
||||
'config.params': {
|
||||
type: 'object',
|
||||
name: 'params',
|
||||
name: 'config.params',
|
||||
title: '',
|
||||
'x-decorator': 'FormItem',
|
||||
properties: {
|
||||
|
@ -1,23 +1,24 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { CloseOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { Button, Modal, Tag } from 'antd';
|
||||
import { DeleteOutlined, CloseOutlined } from '@ant-design/icons';
|
||||
import { ISchema, useForm } from '@formily/react';
|
||||
|
||||
import { Field } from '@formily/core';
|
||||
import { ISchema, RecursionField, useField, useForm } from '@formily/react';
|
||||
import { Registry } from '@nocobase/utils';
|
||||
|
||||
import { Button, Modal, Tag } from 'antd';
|
||||
import React, { useContext } from 'react';
|
||||
import { SchemaComponent, useActionContext, useAPIClient, useCollection, useRequest, useResourceActionContext } from '../..';
|
||||
import { nodeBlockClass, nodeCardClass, nodeClass, nodeHeaderClass, nodeTitleClass } from '../style';
|
||||
import { AddButton, useFlowContext } from '../WorkflowCanvas';
|
||||
|
||||
import { nodeClass, nodeCardClass, nodeHeaderClass, nodeTitleClass, nodeBlockClass } from '../style';
|
||||
|
||||
import query from './query';
|
||||
import create from './create';
|
||||
import update from './update';
|
||||
import destroy from './destroy';
|
||||
import condition from './condition';
|
||||
import parallel from './parallel';
|
||||
import calculation from './calculation';
|
||||
import condition from './condition';
|
||||
import create from './create';
|
||||
import destroy from './destroy';
|
||||
import parallel from './parallel';
|
||||
import query from './query';
|
||||
import update from './update';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -45,7 +46,7 @@ instructions.register('condition', condition);
|
||||
instructions.register('parallel', parallel);
|
||||
instructions.register('calculation', calculation);
|
||||
|
||||
function useUpdateConfigAction() {
|
||||
function useUpdateAction() {
|
||||
const form = useForm();
|
||||
const api = useAPIClient();
|
||||
const ctx = useActionContext();
|
||||
@ -53,14 +54,13 @@ function useUpdateConfigAction() {
|
||||
const data = useNodeContext();
|
||||
return {
|
||||
async run() {
|
||||
await form.submit();
|
||||
await api.resource('flow_nodes', data.id).update({
|
||||
filterByTk: data.id,
|
||||
values: {
|
||||
config: {
|
||||
...data.config,
|
||||
...form.values
|
||||
}
|
||||
},
|
||||
title: form.values.title,
|
||||
config: form.values.config
|
||||
}
|
||||
});
|
||||
ctx.setVisible(false);
|
||||
refresh();
|
||||
@ -148,6 +148,14 @@ export function RemoveButton() {
|
||||
);
|
||||
}
|
||||
|
||||
function Fieldset({ schema }) {
|
||||
const field = useField<Field>();
|
||||
|
||||
return (
|
||||
<RecursionField basePath={field.address} schema={schema} />
|
||||
);
|
||||
}
|
||||
|
||||
export function NodeDefaultView(props) {
|
||||
const { data, children } = props;
|
||||
const instruction = instructions.get(data.type);
|
||||
@ -166,63 +174,75 @@ export function NodeDefaultView(props) {
|
||||
</div>
|
||||
<SchemaComponent
|
||||
scope={instruction.scope}
|
||||
components={instruction.components}
|
||||
components={{
|
||||
...instruction.components,
|
||||
Fieldset
|
||||
}}
|
||||
schema={{
|
||||
type: 'void',
|
||||
properties: {
|
||||
view: instruction.view,
|
||||
...(Object.keys(instruction.fieldset).length
|
||||
? {
|
||||
config: {
|
||||
config: {
|
||||
type: 'void',
|
||||
title: '配置节点',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
title: '配置节点',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
useValues(options) {
|
||||
const data = useNodeContext();
|
||||
return useRequest(() => {
|
||||
return Promise.resolve({ data });
|
||||
}, options);
|
||||
}
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
title: {
|
||||
type: 'string',
|
||||
name: 'title',
|
||||
title: '节点名称',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
config: {
|
||||
type: 'void',
|
||||
title: '配置节点',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
useValues(options) {
|
||||
const node = useNodeContext();
|
||||
return useRequest(() => {
|
||||
return Promise.resolve({ data: node.config });
|
||||
}, options);
|
||||
}
|
||||
},
|
||||
name: 'config',
|
||||
'x-component': 'fieldset',
|
||||
'x-component-props': {},
|
||||
properties: instruction.fieldset
|
||||
},
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer.Footer',
|
||||
properties: {
|
||||
...instruction.fieldset,
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer.Footer',
|
||||
properties: {
|
||||
cancel: {
|
||||
title: '{{t("Cancel")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ cm.useCancelAction }}',
|
||||
},
|
||||
},
|
||||
submit: {
|
||||
title: '{{t("Submit")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: useUpdateConfigAction,
|
||||
},
|
||||
},
|
||||
cancel: {
|
||||
title: '{{t("Cancel")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ cm.useCancelAction }}',
|
||||
},
|
||||
} as ISchema
|
||||
}
|
||||
}
|
||||
},
|
||||
submit: {
|
||||
title: '{{t("Submit")}}',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: useUpdateAction,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as ISchema
|
||||
}
|
||||
}
|
||||
}
|
||||
: {})
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useState } from "react";
|
||||
import { css, cx } from "@emotion/css";
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||
|
||||
import { NodeDefaultView } from ".";
|
||||
import { Branch, useFlowContext } from "../WorkflowCanvas";
|
||||
@ -13,17 +13,37 @@ export default {
|
||||
type: 'parallel',
|
||||
group: 'control',
|
||||
fieldset: {
|
||||
mode: {
|
||||
'config.mode': {
|
||||
type: 'string',
|
||||
name: 'mode',
|
||||
name: 'config.mode',
|
||||
title: '模式',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Radio.Group',
|
||||
'x-component-props': {
|
||||
},
|
||||
enum: [
|
||||
{ value: 'all', label: '全部成功' },
|
||||
{ value: 'any', label: '任意成功' },
|
||||
{
|
||||
value: 'all',
|
||||
label: (
|
||||
<Tooltip
|
||||
title="全部分支都成功后才能继续"
|
||||
placement="bottom"
|
||||
>
|
||||
全部成功 <QuestionCircleOutlined style={{ color: '#999' }} />
|
||||
</Tooltip>
|
||||
)
|
||||
},
|
||||
{
|
||||
value: 'any',
|
||||
label: (
|
||||
<Tooltip
|
||||
title="任意分支成功后就继续"
|
||||
placement="bottom"
|
||||
>
|
||||
任意成功 <QuestionCircleOutlined style={{ color: '#999' }} />
|
||||
</Tooltip>
|
||||
)
|
||||
},
|
||||
// { value: 'race', label: '任意退出' },
|
||||
],
|
||||
default: 'all'
|
||||
|
@ -12,20 +12,20 @@ export default {
|
||||
type: 'query',
|
||||
group: 'model',
|
||||
fieldset: {
|
||||
collection,
|
||||
multiple: {
|
||||
'config.collection': collection,
|
||||
'config.multiple': {
|
||||
type: 'boolean',
|
||||
title: '多条数据',
|
||||
name: 'multiple',
|
||||
name: 'config.multiple',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Checkbox',
|
||||
'x-component-props': {
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
params: {
|
||||
'config.params': {
|
||||
type: 'object',
|
||||
name: 'params',
|
||||
name: 'config.params',
|
||||
title: '',
|
||||
'x-decorator': 'FormItem',
|
||||
properties: {
|
||||
|
@ -7,10 +7,10 @@ export default {
|
||||
type: 'update',
|
||||
group: 'model',
|
||||
fieldset: {
|
||||
collection,
|
||||
params: {
|
||||
'config.collection': collection,
|
||||
'config.params': {
|
||||
type: 'object',
|
||||
name: 'params',
|
||||
name: 'config.params',
|
||||
title: '',
|
||||
'x-decorator': 'FormItem',
|
||||
properties: {
|
||||
|
@ -6,7 +6,7 @@ import { useCollectionFilterOptions } from "../../collection-manager/action-hook
|
||||
export const collection = {
|
||||
type: 'string',
|
||||
title: '数据表',
|
||||
name: 'collection',
|
||||
name: 'config.collection',
|
||||
required: true,
|
||||
'x-reactions': ['{{useCollectionDataSource()}}'],
|
||||
'x-decorator': 'FormItem',
|
||||
@ -16,7 +16,7 @@ export const collection = {
|
||||
export const values = {
|
||||
type: 'object',
|
||||
title: '数据内容',
|
||||
name: 'values',
|
||||
name: 'config.params.values',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-decorator-props': {
|
||||
labelAlign: 'left',
|
||||
@ -29,7 +29,7 @@ export const values = {
|
||||
useProps() {
|
||||
const { getCollectionFields } = useCollectionManager();
|
||||
const { values: form } = useForm();
|
||||
const fields = getCollectionFields(form.collection);
|
||||
const fields = getCollectionFields(form?.config?.collection);
|
||||
return { fields };
|
||||
}
|
||||
}
|
||||
@ -38,7 +38,7 @@ export const values = {
|
||||
export const filter = {
|
||||
type: 'object',
|
||||
title: '筛选条件',
|
||||
name: 'filter',
|
||||
name: 'config.params.filter',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-decorator-props': {
|
||||
labelAlign: 'left',
|
||||
@ -50,14 +50,12 @@ export const filter = {
|
||||
'x-component-props': {
|
||||
useProps() {
|
||||
const { values } = useForm();
|
||||
const options = useCollectionFilterOptions(values.collection);
|
||||
const options = useCollectionFilterOptions(values.config.collection);
|
||||
return {
|
||||
options,
|
||||
className: css`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: .5em 1em;
|
||||
border: 1px dashed #ddd;
|
||||
`
|
||||
};
|
||||
},
|
||||
|
@ -15,16 +15,6 @@ const collection = {
|
||||
required: true,
|
||||
} as ISchema,
|
||||
},
|
||||
// {
|
||||
// type: 'string',
|
||||
// name: 'description',
|
||||
// interface: 'textarea',
|
||||
// uiSchema: {
|
||||
// title: '描述',
|
||||
// type: 'string',
|
||||
// 'x-component': 'TextArea',
|
||||
// } as ISchema,
|
||||
// },
|
||||
{
|
||||
type: 'string',
|
||||
name: 'type',
|
||||
@ -37,6 +27,17 @@ const collection = {
|
||||
enum: [
|
||||
{ value: 'model', label: '数据变动' }
|
||||
],
|
||||
required: true,
|
||||
} as ISchema,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'description',
|
||||
interface: 'textarea',
|
||||
uiSchema: {
|
||||
title: '描述',
|
||||
type: 'string',
|
||||
'x-component': 'Input.TextArea',
|
||||
} as ISchema,
|
||||
},
|
||||
{
|
||||
@ -95,6 +96,13 @@ export const workflowSchema: ISchema = {
|
||||
type: 'void',
|
||||
title: '删除',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ cm.useBulkDestroyAction }}',
|
||||
confirm: {
|
||||
title: "{{t('Delete record')}}",
|
||||
content: "{{t('Are you sure you want to delete it?')}}",
|
||||
},
|
||||
},
|
||||
},
|
||||
create: {
|
||||
type: 'void',
|
||||
@ -114,11 +122,11 @@ export const workflowSchema: ISchema = {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
description: {
|
||||
type: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
type: {
|
||||
description: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
|
@ -16,6 +16,7 @@ function useUpdateConfigAction() {
|
||||
const { refresh } = useResourceActionContext();
|
||||
return {
|
||||
async run() {
|
||||
await form.submit();
|
||||
await api.resource('workflows', record.id).update({
|
||||
filterByTk: record.id,
|
||||
values: {
|
||||
|
@ -21,10 +21,10 @@ export default {
|
||||
'x-component': 'Select',
|
||||
'x-component-props': {
|
||||
options: [
|
||||
{ value: 1, label: '新增数据' },
|
||||
{ value: 2, label: '更新数据' },
|
||||
{ value: 3, label: '新增或更新数据' },
|
||||
{ value: 4, label: '删除数据' }
|
||||
{ value: 1, label: '新增数据后' },
|
||||
{ value: 2, label: '更新数据后' },
|
||||
{ value: 3, label: '新增或更新数据后' },
|
||||
{ value: 4, label: '删除数据后' }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -148,7 +148,7 @@ function minus(a, b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
function multipe(...args) {
|
||||
function multiple(...args) {
|
||||
return args.reduce((result, a) => result * a, 1);
|
||||
}
|
||||
|
||||
@ -162,13 +162,13 @@ function mod(a, b) {
|
||||
|
||||
calculators.register('add', add);
|
||||
calculators.register('minus', minus);
|
||||
calculators.register('multipe', multipe);
|
||||
calculators.register('multiple', multiple);
|
||||
calculators.register('divide', divide);
|
||||
calculators.register('mod', mod);
|
||||
|
||||
calculators.register('+', add);
|
||||
calculators.register('-', minus);
|
||||
calculators.register('*', multipe);
|
||||
calculators.register('*', multiple);
|
||||
calculators.register('/', divide);
|
||||
calculators.register('%', mod);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user