mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-02 11:12:20 +08:00
Merge branch 'main' into next
This commit is contained in:
commit
c616df0cbf
@ -16,7 +16,7 @@ import { useWorkflowExecuted } from '@nocobase/plugin-workflow/client';
|
|||||||
import { useLocalTranslation } from '../../locale';
|
import { useLocalTranslation } from '../../locale';
|
||||||
|
|
||||||
export function UsersAddition() {
|
export function UsersAddition() {
|
||||||
const disabled = useWorkflowExecuted();
|
const executed = useWorkflowExecuted();
|
||||||
/*
|
/*
|
||||||
waiting for improvement
|
waiting for improvement
|
||||||
const array = ArrayItems.useArray();
|
const array = ArrayItems.useArray();
|
||||||
@ -39,12 +39,18 @@ export function UsersAddition() {
|
|||||||
}, [receivers]);
|
}, [receivers]);
|
||||||
|
|
||||||
const button = (
|
const button = (
|
||||||
<Button icon={<PlusOutlined />} type="dashed" block disabled={disabled} className="ant-formily-array-base-addition">
|
<Button
|
||||||
|
icon={<PlusOutlined />}
|
||||||
|
type="dashed"
|
||||||
|
block
|
||||||
|
disabled={executed > 0}
|
||||||
|
className="ant-formily-array-base-addition"
|
||||||
|
>
|
||||||
{t('Add user')}
|
{t('Add user')}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
return disabled ? (
|
return executed ? (
|
||||||
button
|
button
|
||||||
) : (
|
) : (
|
||||||
<Popover
|
<Popover
|
||||||
|
@ -16,7 +16,7 @@ import { useWorkflowExecuted } from '@nocobase/plugin-workflow/client';
|
|||||||
import { useNotificationTranslation } from '../../../../../locale';
|
import { useNotificationTranslation } from '../../../../../locale';
|
||||||
|
|
||||||
export function UsersAddition() {
|
export function UsersAddition() {
|
||||||
const disabled = useWorkflowExecuted();
|
const executed = useWorkflowExecuted();
|
||||||
/*
|
/*
|
||||||
waiting for improvement
|
waiting for improvement
|
||||||
const array = ArrayItems.useArray();
|
const array = ArrayItems.useArray();
|
||||||
@ -39,12 +39,18 @@ export function UsersAddition() {
|
|||||||
}, [receivers]);
|
}, [receivers]);
|
||||||
|
|
||||||
const button = (
|
const button = (
|
||||||
<Button icon={<PlusOutlined />} type="dashed" block disabled={disabled} className="ant-formily-array-base-addition">
|
<Button
|
||||||
|
icon={<PlusOutlined />}
|
||||||
|
type="dashed"
|
||||||
|
block
|
||||||
|
disabled={executed > 0}
|
||||||
|
className="ant-formily-array-base-addition"
|
||||||
|
>
|
||||||
{t('Add user')}
|
{t('Add user')}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
return disabled ? (
|
return executed ? (
|
||||||
button
|
button
|
||||||
) : (
|
) : (
|
||||||
<Popover
|
<Popover
|
||||||
|
@ -80,7 +80,7 @@ function NodeComponent({ data }) {
|
|||||||
shape="circle"
|
shape="circle"
|
||||||
icon={<PlusOutlined />}
|
icon={<PlusOutlined />}
|
||||||
onClick={() => setBranchCount(branchCount - 1)}
|
onClick={() => setBranchCount(branchCount - 1)}
|
||||||
disabled={executed}
|
disabled={executed > 0}
|
||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -92,7 +92,7 @@ function NodeComponent({ data }) {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
title={langAddBranch}
|
title={langAddBranch}
|
||||||
className={css`
|
className={css`
|
||||||
visibility: ${executed ? 'hidden' : 'visible'};
|
visibility: ${executed > 0 ? 'hidden' : 'visible'};
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
@ -112,7 +112,7 @@ function NodeComponent({ data }) {
|
|||||||
`}
|
`}
|
||||||
size="small"
|
size="small"
|
||||||
onClick={() => setBranchCount(branchCount + 1)}
|
onClick={() => setBranchCount(branchCount + 1)}
|
||||||
disabled={executed}
|
disabled={executed > 0}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
@ -92,7 +92,7 @@ export function AddButton(props: AddButtonProps) {
|
|||||||
items: groups,
|
items: groups,
|
||||||
onClick,
|
onClick,
|
||||||
}}
|
}}
|
||||||
disabled={executed}
|
disabled={Boolean(executed)}
|
||||||
overlayClassName={css`
|
overlayClassName={css`
|
||||||
.ant-dropdown-menu-root {
|
.ant-dropdown-menu-root {
|
||||||
max-height: 30em;
|
max-height: 30em;
|
||||||
|
@ -463,8 +463,8 @@ export function WorkflowCanvas() {
|
|||||||
key: `${item.id}`,
|
key: `${item.id}`,
|
||||||
icon: item.current ? <RightOutlined /> : null,
|
icon: item.current ? <RightOutlined /> : null,
|
||||||
className: cx({
|
className: cx({
|
||||||
executed: item.versionStats.executed,
|
executed: item.versionStats.executed > 0,
|
||||||
unexecuted: !item.versionStats.executed,
|
unexecuted: item.versionStats.executed == 0,
|
||||||
enabled: item.enabled,
|
enabled: item.enabled,
|
||||||
}),
|
}),
|
||||||
label: (
|
label: (
|
||||||
|
@ -73,7 +73,7 @@ export function AssignedFieldsFormSchemaConfig(props) {
|
|||||||
() =>
|
() =>
|
||||||
createForm({
|
createForm({
|
||||||
initialValues: params.values,
|
initialValues: params.values,
|
||||||
disabled: executed,
|
disabled: Boolean(executed),
|
||||||
effects() {
|
effects() {
|
||||||
onFormValuesChange((f) => {
|
onFormValuesChange((f) => {
|
||||||
setValuesIn('params.values', toJS(f.values));
|
setValuesIn('params.values', toJS(f.values));
|
||||||
@ -115,7 +115,7 @@ export function AssignedFieldsFormSchemaConfig(props) {
|
|||||||
});
|
});
|
||||||
setValuesIn('params.values', nextValues);
|
setValuesIn('params.values', nextValues);
|
||||||
},
|
},
|
||||||
[collectionName, props.onChange],
|
[collectionName, form.values, props, setValuesIn],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -9,12 +9,12 @@
|
|||||||
|
|
||||||
import { useFlowContext } from '../FlowContext';
|
import { useFlowContext } from '../FlowContext';
|
||||||
|
|
||||||
export function useWorkflowExecuted() {
|
export function useWorkflowExecuted(): bigint {
|
||||||
const { workflow } = useFlowContext();
|
const { workflow } = useFlowContext();
|
||||||
return Boolean(workflow?.versionStats?.executed);
|
return BigInt(workflow?.versionStats?.executed || 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useWorkflowAnyExecuted() {
|
export function useWorkflowAnyExecuted(): bigint {
|
||||||
const { workflow } = useFlowContext();
|
const { workflow } = useFlowContext();
|
||||||
return Boolean(workflow?.stats?.executed);
|
return BigInt(workflow?.stats?.executed || 0);
|
||||||
}
|
}
|
||||||
|
@ -527,7 +527,7 @@ export function NodeDefaultView(props) {
|
|||||||
const values = cloneDeep(data.config);
|
const values = cloneDeep(data.config);
|
||||||
return createForm({
|
return createForm({
|
||||||
initialValues: values,
|
initialValues: values,
|
||||||
disabled: executed,
|
disabled: Boolean(executed),
|
||||||
});
|
});
|
||||||
}, [data, workflow]);
|
}, [data, workflow]);
|
||||||
|
|
||||||
@ -621,7 +621,7 @@ export function NodeDefaultView(props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Input.TextArea
|
<Input.TextArea
|
||||||
disabled={executed}
|
disabled={Boolean(executed)}
|
||||||
value={editingTitle}
|
value={editingTitle}
|
||||||
onChange={(ev) => setEditingTitle(ev.target.value)}
|
onChange={(ev) => setEditingTitle(ev.target.value)}
|
||||||
onBlur={(ev) => onChangeTitle(ev.target.value)}
|
onBlur={(ev) => onChangeTitle(ev.target.value)}
|
||||||
|
@ -184,7 +184,7 @@ export const TriggerConfig = () => {
|
|||||||
const values = cloneDeep(workflow.config);
|
const values = cloneDeep(workflow.config);
|
||||||
return createForm({
|
return createForm({
|
||||||
initialValues: values,
|
initialValues: values,
|
||||||
disabled: executed,
|
disabled: Boolean(executed),
|
||||||
});
|
});
|
||||||
}, [workflow]);
|
}, [workflow]);
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ export const TriggerConfig = () => {
|
|||||||
onChange={(ev) => setEditingTitle(ev.target.value)}
|
onChange={(ev) => setEditingTitle(ev.target.value)}
|
||||||
onBlur={(ev) => onChangeTitle(ev.target.value)}
|
onBlur={(ev) => onChangeTitle(ev.target.value)}
|
||||||
autoSize
|
autoSize
|
||||||
disabled={executed}
|
disabled={Boolean(executed)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ActionContextProvider
|
<ActionContextProvider
|
||||||
|
@ -609,5 +609,26 @@ describe('workflow > Plugin', () => {
|
|||||||
expect(s2.executed).toBe(0);
|
expect(s2.executed).toBe(0);
|
||||||
expect(vs2.executed).toBe(0);
|
expect(vs2.executed).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.skipIf(process.env.DB_DIALECT === 'sqlite')('bigint stats', async () => {
|
||||||
|
const WorkflowRepo = app.db.getRepository('workflows');
|
||||||
|
|
||||||
|
const w1 = await WorkflowRepo.create({
|
||||||
|
values: {
|
||||||
|
enabled: true,
|
||||||
|
type: 'syncTrigger',
|
||||||
|
key: 'abc',
|
||||||
|
current: true,
|
||||||
|
},
|
||||||
|
hooks: false,
|
||||||
|
});
|
||||||
|
await w1.createStats({ executed: '10000000000000001' });
|
||||||
|
await w1.createVersionStats({ executed: '10000000000000001' });
|
||||||
|
|
||||||
|
const s1 = await w1.getStats();
|
||||||
|
const vs1 = await w1.getVersionStats();
|
||||||
|
expect(s1.executed).toBe('10000000000000001');
|
||||||
|
expect(vs1.executed).toBe('10000000000000001');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -50,7 +50,7 @@ describe('workflow > actions > workflows', () => {
|
|||||||
expect(data.type).toBe('echo');
|
expect(data.type).toBe('echo');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('create in executed workflow', async () => {
|
it.skipIf(process.env.DB_DIALECT === 'sqlite')('create in executed workflow', async () => {
|
||||||
const workflow = await WorkflowModel.create({
|
const workflow = await WorkflowModel.create({
|
||||||
enabled: true,
|
enabled: true,
|
||||||
type: 'asyncTrigger',
|
type: 'asyncTrigger',
|
||||||
@ -58,12 +58,22 @@ describe('workflow > actions > workflows', () => {
|
|||||||
await workflow.stats.update({ executed: 1 });
|
await workflow.stats.update({ executed: 1 });
|
||||||
await workflow.versionStats.update({ executed: 1 });
|
await workflow.versionStats.update({ executed: 1 });
|
||||||
|
|
||||||
const { status } = await agent.resource('workflows.nodes', workflow.id).create({
|
const res1 = await agent.resource('workflows.nodes', workflow.id).create({
|
||||||
values: {
|
values: {
|
||||||
type: 'echo',
|
type: 'echo',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(status).toBe(400);
|
expect(res1.status).toBe(400);
|
||||||
|
|
||||||
|
await workflow.stats.update({ executed: '10000000000000001' });
|
||||||
|
await workflow.versionStats.update({ executed: '10000000000000001' });
|
||||||
|
|
||||||
|
const res2 = await agent.resource('workflows.nodes', workflow.id).create({
|
||||||
|
values: {
|
||||||
|
type: 'echo',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(res2.status).toBe(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('create as head', async () => {
|
it('create as head', async () => {
|
||||||
|
@ -130,7 +130,7 @@ export async function destroy(context: Context, next) {
|
|||||||
fields: [...fields, 'workflowId'],
|
fields: [...fields, 'workflowId'],
|
||||||
appends: ['upstream', 'downstream', 'workflow.versionStats.executed'],
|
appends: ['upstream', 'downstream', 'workflow.versionStats.executed'],
|
||||||
});
|
});
|
||||||
if (instance.workflow.versionStats.executed) {
|
if (instance.workflow.versionStats.executed > 0) {
|
||||||
context.throw(400, 'Nodes in executed workflow could not be deleted');
|
context.throw(400, 'Nodes in executed workflow could not be deleted');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ export async function update(context: Context, next) {
|
|||||||
appends: ['workflow.versionStats.executed'],
|
appends: ['workflow.versionStats.executed'],
|
||||||
transaction,
|
transaction,
|
||||||
});
|
});
|
||||||
if (workflow.versionStats.executed) {
|
if (workflow.versionStats.executed > 0) {
|
||||||
context.throw(400, 'Nodes in executed workflow could not be reconfigured');
|
context.throw(400, 'Nodes in executed workflow could not be reconfigured');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ export async function update(context: Context, next) {
|
|||||||
filterByTk,
|
filterByTk,
|
||||||
appends: ['versionStats'],
|
appends: ['versionStats'],
|
||||||
});
|
});
|
||||||
if (workflow.versionStats.executed) {
|
if (workflow.versionStats.executed > 0) {
|
||||||
return context.throw(400, 'config of executed workflow can not be updated');
|
return context.throw(400, 'config of executed workflow can not be updated');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ export async function execute(context: Context, next) {
|
|||||||
filter: { key: workflow.key },
|
filter: { key: workflow.key },
|
||||||
});
|
});
|
||||||
let newVersion;
|
let newVersion;
|
||||||
if (!executed && autoRevision) {
|
if (executed == 0 && autoRevision) {
|
||||||
newVersion = await repository.revision({
|
newVersion = await repository.revision({
|
||||||
filterByTk: workflow.id,
|
filterByTk: workflow.id,
|
||||||
filter: { key: workflow.key },
|
filter: { key: workflow.key },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user