mirror of
https://github.com/nocobase/nocobase.git
synced 2026-09-21 05:44:51 +08:00
Merge branch 'main' into next
This commit is contained in:
@@ -60,7 +60,9 @@ type FlowPageProps = {
|
||||
type FlowPageViewContext = FlowEngineContext & {
|
||||
view?: {
|
||||
inputArgs?: {
|
||||
filterByTk?: unknown;
|
||||
isMobileLayout?: unknown;
|
||||
sourceId?: unknown;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -102,6 +104,10 @@ export const FlowPage = React.memo((props: FlowPageProps & Record<string, unknow
|
||||
subType: 'object',
|
||||
use: pageModelClass,
|
||||
};
|
||||
const isRuntimeRecordScopedPage =
|
||||
!flowEngine.context.flowSettingsEnabled &&
|
||||
(typeof ctx?.view?.inputArgs?.filterByTk !== 'undefined' ||
|
||||
typeof ctx?.view?.inputArgs?.sourceId !== 'undefined');
|
||||
if (shouldInjectDefaultChildTab) {
|
||||
const tabTitle = defaultTabTitle || flowEngine.translate?.('Details');
|
||||
options['subModels'] = {
|
||||
@@ -128,7 +134,9 @@ export const FlowPage = React.memo((props: FlowPageProps & Record<string, unknow
|
||||
},
|
||||
};
|
||||
}
|
||||
const data = await flowEngine.loadOrCreateModel(options, { skipSave: !flowEngine.context.flowSettingsEnabled });
|
||||
const data =
|
||||
(isRuntimeRecordScopedPage && (await flowEngine.loadModel({ ...options, refresh: true }))) ||
|
||||
(await flowEngine.loadOrCreateModel(options, { skipSave: !flowEngine.context.flowSettingsEnabled }));
|
||||
if (data?.uid && onModelLoaded) {
|
||||
data.context.addDelegate(ctx);
|
||||
bindViewLayoutState(data, ctx);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { FlowPage } from '../FlowPage';
|
||||
|
||||
type TestContextProperty = {
|
||||
@@ -71,10 +71,15 @@ const createPageModel = (): TestPageModel => {
|
||||
};
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
flowSettingsEnabled: false,
|
||||
loadModel: vi.fn(),
|
||||
loadOrCreateModel: vi.fn(),
|
||||
rendererMobileStates: [] as boolean[],
|
||||
rendererProps: undefined as RendererProps | undefined,
|
||||
model: undefined as TestPageModel | undefined,
|
||||
viewFilterByTk: undefined as unknown,
|
||||
viewInputMobileLayout: true as boolean | undefined,
|
||||
viewSourceId: undefined as unknown,
|
||||
contextMobileLayout: undefined as boolean | undefined,
|
||||
}));
|
||||
|
||||
@@ -94,15 +99,20 @@ vi.mock('@nocobase/flow-engine', async () => {
|
||||
}),
|
||||
useFlowEngine: vi.fn(() => ({
|
||||
getModelClassAsync: vi.fn(async () => TestPageModelClass),
|
||||
loadOrCreateModel: vi.fn(async () => mocks.model),
|
||||
context: {},
|
||||
loadModel: mocks.loadModel,
|
||||
loadOrCreateModel: mocks.loadOrCreateModel,
|
||||
context: {
|
||||
flowSettingsEnabled: mocks.flowSettingsEnabled,
|
||||
},
|
||||
translate: vi.fn((value: string) => value),
|
||||
})),
|
||||
useFlowModelById: vi.fn(() => mocks.model),
|
||||
useFlowViewContext: vi.fn(() => ({
|
||||
view: {
|
||||
inputArgs: {
|
||||
...(typeof mocks.viewFilterByTk !== 'undefined' ? { filterByTk: mocks.viewFilterByTk } : {}),
|
||||
...(typeof mocks.viewInputMobileLayout === 'boolean' ? { isMobileLayout: mocks.viewInputMobileLayout } : {}),
|
||||
...(typeof mocks.viewSourceId !== 'undefined' ? { sourceId: mocks.viewSourceId } : {}),
|
||||
},
|
||||
},
|
||||
...(typeof mocks.contextMobileLayout === 'boolean' ? { isMobileLayout: mocks.contextMobileLayout } : {}),
|
||||
@@ -154,11 +164,21 @@ vi.mock('ahooks', async () => {
|
||||
});
|
||||
|
||||
describe('FlowPage', () => {
|
||||
beforeEach(() => {
|
||||
mocks.loadModel.mockImplementation(async () => null);
|
||||
mocks.loadOrCreateModel.mockImplementation(async () => mocks.model);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mocks.flowSettingsEnabled = false;
|
||||
mocks.loadModel.mockReset();
|
||||
mocks.loadOrCreateModel.mockReset();
|
||||
mocks.rendererMobileStates = [];
|
||||
mocks.rendererProps = undefined;
|
||||
mocks.model = undefined;
|
||||
mocks.viewFilterByTk = undefined;
|
||||
mocks.viewInputMobileLayout = true;
|
||||
mocks.viewSourceId = undefined;
|
||||
mocks.contextMobileLayout = undefined;
|
||||
});
|
||||
|
||||
@@ -203,4 +223,31 @@ describe('FlowPage', () => {
|
||||
expect(mocks.rendererMobileStates[0]).toBe(expected);
|
||||
},
|
||||
);
|
||||
|
||||
it('reloads runtime page models for record scoped views', async () => {
|
||||
mocks.model = createPageModel();
|
||||
mocks.viewFilterByTk = 1;
|
||||
mocks.loadModel.mockImplementation(async () => mocks.model);
|
||||
|
||||
render(<FlowPage onModelLoaded={vi.fn()} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mocks.loadModel).toHaveBeenCalled();
|
||||
});
|
||||
expect(mocks.loadModel.mock.calls[0]?.[0]).toMatchObject({ refresh: true });
|
||||
expect(mocks.loadOrCreateModel).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('keeps configured page model cache behavior in flow settings mode', async () => {
|
||||
mocks.flowSettingsEnabled = true;
|
||||
mocks.model = createPageModel();
|
||||
mocks.viewFilterByTk = 1;
|
||||
|
||||
render(<FlowPage onModelLoaded={vi.fn()} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mocks.loadOrCreateModel).toHaveBeenCalled();
|
||||
});
|
||||
expect(mocks.loadModel).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user