fix(plugin-workflow): fix executed check on bigint (#7091)

* fix(plugin-workflow): fix executed check on bigint

* fix(plugin-workflow): fix test case

* fix(plugin-workflow): fix types

* fix(plugin-workflow): fix test case

* fix(plugin-workflow): fix types

* fix: types
This commit is contained in:
Junyi 2025-06-18 18:52:11 +08:00 committed by GitHub
parent d70eb68651
commit cca6b0faaf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 72 additions and 29 deletions

View File

@ -16,7 +16,7 @@ import { useWorkflowExecuted } from '@nocobase/plugin-workflow/client';
import { useLocalTranslation } from '../../locale';
export function UsersAddition() {
const disabled = useWorkflowExecuted();
const executed = useWorkflowExecuted();
/*
waiting for improvement
const array = ArrayItems.useArray();
@ -39,12 +39,18 @@ export function UsersAddition() {
}, [receivers]);
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')}
</Button>
);
return disabled ? (
return executed ? (
button
) : (
<Popover

View File

@ -16,7 +16,7 @@ import { useWorkflowExecuted } from '@nocobase/plugin-workflow/client';
import { useNotificationTranslation } from '../../../../../locale';
export function UsersAddition() {
const disabled = useWorkflowExecuted();
const executed = useWorkflowExecuted();
/*
waiting for improvement
const array = ArrayItems.useArray();
@ -39,12 +39,18 @@ export function UsersAddition() {
}, [receivers]);
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')}
</Button>
);
return disabled ? (
return executed ? (
button
) : (
<Popover

View File

@ -80,7 +80,7 @@ function NodeComponent({ data }) {
shape="circle"
icon={<PlusOutlined />}
onClick={() => setBranchCount(branchCount - 1)}
disabled={executed}
disabled={executed > 0}
size="small"
/>
</div>
@ -92,7 +92,7 @@ function NodeComponent({ data }) {
<Tooltip
title={langAddBranch}
className={css`
visibility: ${executed ? 'hidden' : 'visible'};
visibility: ${executed > 0 ? 'hidden' : 'visible'};
`}
>
<Button
@ -112,7 +112,7 @@ function NodeComponent({ data }) {
`}
size="small"
onClick={() => setBranchCount(branchCount + 1)}
disabled={executed}
disabled={executed > 0}
/>
</Tooltip>
</div>

View File

@ -92,7 +92,7 @@ export function AddButton(props: AddButtonProps) {
items: groups,
onClick,
}}
disabled={executed}
disabled={Boolean(executed)}
overlayClassName={css`
.ant-dropdown-menu-root {
max-height: 30em;

View File

@ -463,8 +463,8 @@ export function WorkflowCanvas() {
key: `${item.id}`,
icon: item.current ? <RightOutlined /> : null,
className: cx({
executed: item.versionStats.executed,
unexecuted: !item.versionStats.executed,
executed: item.versionStats.executed > 0,
unexecuted: item.versionStats.executed == 0,
enabled: item.enabled,
}),
label: (

View File

@ -73,7 +73,7 @@ export function AssignedFieldsFormSchemaConfig(props) {
() =>
createForm({
initialValues: params.values,
disabled: executed,
disabled: Boolean(executed),
effects() {
onFormValuesChange((f) => {
setValuesIn('params.values', toJS(f.values));
@ -115,7 +115,7 @@ export function AssignedFieldsFormSchemaConfig(props) {
});
setValuesIn('params.values', nextValues);
},
[collectionName, props.onChange],
[collectionName, form.values, props, setValuesIn],
);
return (

View File

@ -9,12 +9,12 @@
import { useFlowContext } from '../FlowContext';
export function useWorkflowExecuted() {
export function useWorkflowExecuted(): bigint {
const { workflow } = useFlowContext();
return Boolean(workflow?.versionStats?.executed);
return BigInt(workflow?.versionStats?.executed || 0);
}
export function useWorkflowAnyExecuted() {
export function useWorkflowAnyExecuted(): bigint {
const { workflow } = useFlowContext();
return Boolean(workflow?.stats?.executed);
return BigInt(workflow?.stats?.executed || 0);
}

View File

@ -527,7 +527,7 @@ export function NodeDefaultView(props) {
const values = cloneDeep(data.config);
return createForm({
initialValues: values,
disabled: executed,
disabled: Boolean(executed),
});
}, [data, workflow]);
@ -621,7 +621,7 @@ export function NodeDefaultView(props) {
</div>
</div>
<Input.TextArea
disabled={executed}
disabled={Boolean(executed)}
value={editingTitle}
onChange={(ev) => setEditingTitle(ev.target.value)}
onBlur={(ev) => onChangeTitle(ev.target.value)}

View File

@ -184,7 +184,7 @@ export const TriggerConfig = () => {
const values = cloneDeep(workflow.config);
return createForm({
initialValues: values,
disabled: executed,
disabled: Boolean(executed),
});
}, [workflow]);
@ -285,7 +285,7 @@ export const TriggerConfig = () => {
onChange={(ev) => setEditingTitle(ev.target.value)}
onBlur={(ev) => onChangeTitle(ev.target.value)}
autoSize
disabled={executed}
disabled={Boolean(executed)}
/>
</div>
<ActionContextProvider

View File

@ -609,5 +609,26 @@ describe('workflow > Plugin', () => {
expect(s2.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');
});
});
});

View File

@ -50,7 +50,7 @@ describe('workflow > actions > workflows', () => {
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({
enabled: true,
type: 'asyncTrigger',
@ -58,12 +58,22 @@ describe('workflow > actions > workflows', () => {
await workflow.stats.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: {
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 () => {

View File

@ -130,7 +130,7 @@ export async function destroy(context: Context, next) {
fields: [...fields, 'workflowId'],
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');
}
@ -204,7 +204,7 @@ export async function update(context: Context, next) {
appends: ['workflow.versionStats.executed'],
transaction,
});
if (workflow.versionStats.executed) {
if (workflow.versionStats.executed > 0) {
context.throw(400, 'Nodes in executed workflow could not be reconfigured');
}

View File

@ -26,7 +26,7 @@ export async function update(context: Context, next) {
filterByTk,
appends: ['versionStats'],
});
if (workflow.versionStats.executed) {
if (workflow.versionStats.executed > 0) {
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 },
});
let newVersion;
if (!executed && autoRevision) {
if (executed == 0 && autoRevision) {
newVersion = await repository.revision({
filterByTk: workflow.id,
filter: { key: workflow.key },