diff --git a/packages/plugins/@nocobase/plugin-users/src/client-v2/__tests__/UserFormDrawer.test.tsx b/packages/plugins/@nocobase/plugin-users/src/client-v2/__tests__/UserFormDrawer.test.tsx index a02f25a552e..3e9ecd3429f 100644 --- a/packages/plugins/@nocobase/plugin-users/src/client-v2/__tests__/UserFormDrawer.test.tsx +++ b/packages/plugins/@nocobase/plugin-users/src/client-v2/__tests__/UserFormDrawer.test.tsx @@ -8,14 +8,26 @@ */ import React from 'react'; -import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'; import UserFormDrawer from '../pages/UserFormDrawer'; import { ADMIN_PROFILE_CREATE_FORM_MODEL_UID, ADMIN_PROFILE_EDIT_FORM_MODEL_UID, } from '../shared/adminProfileFormModels'; -const { create, update, save, findOne, createModelAsync, submit, close, success, toErrMessages } = vi.hoisted(() => ({ +const { + create, + update, + save, + findOne, + createModelAsync, + submit, + close, + success, + toErrMessages, + flowModelRenderer, + flowSettingsEnabled, +} = vi.hoisted(() => ({ create: vi.fn(), update: vi.fn(), save: vi.fn(), @@ -25,6 +37,8 @@ const { create, update, save, findOne, createModelAsync, submit, close, success, close: vi.fn(), success: vi.fn(), toErrMessages: vi.fn(), + flowModelRenderer: vi.fn(), + flowSettingsEnabled: { value: false }, })); vi.mock('@nocobase/client-v2', async () => { @@ -132,12 +146,17 @@ vi.mock('@nocobase/flow-engine', () => { paddingLG: 24, colorBorderSecondary: '#f0f0f0', }, - flowSettingsEnabled: false, + get flowSettingsEnabled() { + return flowSettingsEnabled.value; + }, }; const flowViewContext = {}; return { - FlowModelRenderer: () =>
, + FlowModelRenderer: React.memo((props: { showFlowSettings?: unknown }) => { + flowModelRenderer(props); + return
; + }), MultiRecordResource: class MultiRecordResource {}, useFlowEngine: () => flowEngine, useFlowContext: () => flowContext, @@ -208,6 +227,8 @@ describe('UserFormDrawer', () => { close.mockReset(); success.mockReset(); toErrMessages.mockReset(); + flowModelRenderer.mockReset(); + flowSettingsEnabled.value = false; }); afterEach(() => { @@ -316,6 +337,34 @@ describe('UserFormDrawer', () => { expect(close).not.toHaveBeenCalled(); }); + it('should keep the form renderer stable while submitting in UI editor mode', async () => { + flowSettingsEnabled.value = true; + let finishSubmit: (() => void) | undefined; + submit.mockImplementation( + () => + new Promise((resolve) => { + finishSubmit = resolve; + }), + ); + + render( undefined} />); + + await waitFor(() => { + expect(flowModelRenderer).toHaveBeenCalledTimes(1); + }); + + fireEvent.click(screen.getByRole('button', { name: 'Submit' })); + + await waitFor(() => { + expect(submit).toHaveBeenCalledTimes(1); + }); + expect(flowModelRenderer).toHaveBeenCalledTimes(1); + + await act(async () => { + finishSubmit?.(); + }); + }); + it('should show the API error and keep the drawer open when creating a user fails', async () => { const error = new Error('Request failed'); create.mockRejectedValue(error); diff --git a/packages/plugins/@nocobase/plugin-users/src/client-v2/pages/UserFormDrawer.tsx b/packages/plugins/@nocobase/plugin-users/src/client-v2/pages/UserFormDrawer.tsx index 9ad4319b298..189e6a779ce 100644 --- a/packages/plugins/@nocobase/plugin-users/src/client-v2/pages/UserFormDrawer.tsx +++ b/packages/plugins/@nocobase/plugin-users/src/client-v2/pages/UserFormDrawer.tsx @@ -76,6 +76,11 @@ const userFormErrorClassName = css` margin: 24px 24px 0; `; +const userFormFlowSettings = { + showBackground: false, + showBorder: false, +} as const; + type PersistedFlowModelTree = CreateModelOptions & Record; const privateUserFormModels = { @@ -284,10 +289,7 @@ export default function UserFormDrawer(props: UserFormDrawerProps) { ) : null}
{model ? ( - + ) : ( )}