@nocobase/client-v2 2.2.0-beta.3 → 2.2.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/RouteRepository.d.ts +21 -6
- package/es/components/form/JsonTextArea.d.ts +2 -1
- package/es/components/form/VariableJsonTextArea.d.ts +19 -0
- package/es/components/form/index.d.ts +1 -0
- package/es/components/index.d.ts +1 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +2 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.d.ts +2 -1
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +2 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.d.ts +3 -2
- package/es/flow/admin-shell/admin-layout/AdminLayoutSlotModels.d.ts +4 -0
- package/es/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.d.ts +6 -0
- package/es/flow/components/FieldAssignRulesEditor.d.ts +3 -1
- package/es/flow/models/base/GridModel.d.ts +1 -1
- package/es/flow/models/blocks/filter-form/FilterFormBlockModel.d.ts +5 -0
- package/es/flow/models/blocks/form/FormBlockModel.d.ts +4 -0
- package/es/flow/models/blocks/form/value-runtime/rules.d.ts +21 -0
- package/es/flow/models/blocks/form/value-runtime/runtime.d.ts +21 -0
- package/es/flow/models/blocks/form/value-runtime/types.d.ts +2 -2
- package/es/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.d.ts +2 -0
- package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.d.ts +1 -0
- package/es/flow/utils/dateTimeDisplayProps.d.ts +49 -0
- package/es/flow-compat/FieldValidation.d.ts +2 -1
- package/es/index.d.ts +2 -1
- package/es/index.mjs +167 -121
- package/lib/index.js +167 -121
- package/package.json +7 -7
- package/src/RouteRepository.ts +126 -24
- package/src/__tests__/RouteRepository.test.ts +216 -0
- package/src/__tests__/exports.test.ts +16 -0
- package/src/__tests__/settings-center.test.tsx +33 -0
- package/src/components/form/JsonTextArea.tsx +21 -11
- package/src/components/form/VariableJsonTextArea.tsx +175 -0
- package/src/components/form/__tests__/JsonTextArea.test.tsx +43 -0
- package/src/components/form/__tests__/VariableJsonTextArea.test.tsx +86 -0
- package/src/components/form/index.tsx +1 -0
- package/src/components/index.ts +1 -0
- package/src/flow/__tests__/FlowRoute.test.tsx +443 -5
- package/src/flow/actions/__tests__/fieldLinkageRules.scopeDepth.test.ts +150 -1
- package/src/flow/actions/__tests__/linkageAssignField.legacy.test.ts +135 -0
- package/src/flow/actions/__tests__/linkageRules.hiddenSync.restore.test.ts +19 -5
- package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +92 -0
- package/src/flow/actions/customVariable.tsx +1 -2
- package/src/flow/actions/dateTimeFormat.tsx +42 -28
- package/src/flow/actions/linkageRules.tsx +122 -34
- package/src/flow/actions/runjs.tsx +2 -14
- package/src/flow/actions/validation.tsx +62 -30
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +33 -10
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.test.tsx +310 -0
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +44 -8
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.ts +5 -3
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +61 -9
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.tsx +71 -8
- package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +1 -1
- package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +21 -8
- package/src/flow/admin-shell/admin-layout/HelpLite.tsx +1 -3
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutComponent.test.tsx +188 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +99 -0
- package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +166 -2
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +20 -0
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +33 -5
- package/src/flow/components/DefaultValue.tsx +1 -2
- package/src/flow/components/DynamicFlowsIcon.tsx +447 -126
- package/src/flow/components/FieldAssignRulesEditor.tsx +62 -12
- package/src/flow/components/FlowRoute.tsx +56 -11
- package/src/flow/components/__tests__/DynamicFlowsIcon.test.tsx +148 -2
- package/src/flow/components/__tests__/FieldAssignRulesEditor.test.tsx +81 -4
- package/src/flow/components/code-editor/__tests__/useCodeRunner.test.tsx +2 -17
- package/src/flow/components/code-editor/hooks/useCodeRunner.ts +2 -14
- package/src/flow/components/code-editor/runjsDiagnostics.ts +8 -45
- package/src/flow/flows/editMarkdownFlow.tsx +1 -1
- package/src/flow/index.ts +1 -1
- package/src/flow/internal/utils/operatorSchemaHelper.ts +15 -1
- package/src/flow/models/actions/JSActionModel.tsx +2 -7
- package/src/flow/models/actions/JSCollectionActionModel.tsx +2 -7
- package/src/flow/models/actions/JSItemActionModel.tsx +2 -7
- package/src/flow/models/actions/JSRecordActionModel.tsx +2 -7
- package/src/flow/models/base/ActionModel.tsx +12 -1
- package/src/flow/models/base/GridModel.tsx +38 -7
- package/src/flow/models/base/PageModel/PageModel.tsx +4 -1
- package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +28 -4
- package/src/flow/models/base/__tests__/ActionModel.test.ts +83 -0
- package/src/flow/models/base/__tests__/GridModel.dragSnapshotContainer.test.ts +239 -1
- package/src/flow/models/base/__tests__/transformRowsToSingleColumn.test.ts +48 -0
- package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +31 -3
- package/src/flow/models/blocks/filter-form/FilterFormJSActionModel.tsx +2 -7
- package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +77 -0
- package/src/flow/models/blocks/filter-manager/flow-actions/__tests__/customizeFilterRender.test.tsx +56 -1
- package/src/flow/models/blocks/form/EditFormModel.tsx +1 -0
- package/src/flow/models/blocks/form/FormBlockModel.tsx +7 -0
- package/src/flow/models/blocks/form/JSFormActionModel.tsx +2 -7
- package/src/flow/models/blocks/form/__tests__/FormBlockModel.test.tsx +17 -0
- package/src/flow/models/blocks/form/value-runtime/__tests__/runtime.test.ts +880 -102
- package/src/flow/models/blocks/form/value-runtime/rules.ts +445 -13
- package/src/flow/models/blocks/form/value-runtime/runtime.ts +257 -13
- package/src/flow/models/blocks/form/value-runtime/types.ts +2 -2
- package/src/flow/models/blocks/js-block/JSBlock.tsx +2 -7
- package/src/flow/models/blocks/table/JSColumnModel.tsx +1 -9
- package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +1 -1
- package/src/flow/models/blocks/table/TableBlockModel.tsx +13 -3
- package/src/flow/models/blocks/table/TableColumnModel.tsx +36 -3
- package/src/flow/models/blocks/table/__tests__/TableActionsColumnModel.test.tsx +54 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.mobileSettingsButtons.test.tsx +78 -0
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +159 -1
- package/src/flow/models/fields/AssociationFieldModel/AssociationFieldModel.tsx +1 -1
- package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.tsx +29 -6
- package/src/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.tsx +16 -4
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.tsx +24 -1
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +13 -1
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableColumnModel.rowRecord.test.ts +12 -0
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableFieldModel.reset.test.ts +180 -0
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +6 -4
- package/src/flow/models/fields/AssociationFieldModel/__tests__/AssociationFieldModel.updateAssociation.test.ts +72 -0
- package/src/flow/models/fields/AssociationFieldModel/__tests__/RecordPickerFieldModel.itemContext.test.ts +23 -0
- package/src/flow/models/fields/ClickableFieldModel.tsx +5 -0
- package/src/flow/models/fields/DisplayDateTimeFieldModel.tsx +29 -1
- package/src/flow/models/fields/InputFieldModel.tsx +14 -22
- package/src/flow/models/fields/JSEditableFieldModel.tsx +2 -11
- package/src/flow/models/fields/JSFieldModel.tsx +2 -7
- package/src/flow/models/fields/JSItemModel.tsx +2 -14
- package/src/flow/models/fields/SelectFieldModel.tsx +6 -4
- package/src/flow/models/fields/__tests__/DisplayDateTimeFieldModel.test.tsx +96 -0
- package/src/flow/models/fields/__tests__/InputFieldModel.test.tsx +17 -0
- package/src/flow/models/fields/__tests__/SelectFieldModel.test.tsx +43 -0
- package/src/flow/models/topbar/TopbarActionModel.tsx +93 -10
- package/src/flow/utils/__tests__/dateTimeFormat.test.ts +258 -0
- package/src/flow/utils/dateTimeDisplayProps.ts +135 -0
- package/src/flow-compat/FieldValidation.tsx +122 -60
- package/src/flow-compat/Popover.tsx +43 -4
- package/src/flow-compat/__tests__/Popover.test.tsx +34 -0
- package/src/index.ts +8 -1
- package/src/layout-manager/__tests__/LayoutRoute.test.tsx +41 -1
- package/src/settings-center/AdminSettingsLayout.tsx +3 -0
- package/src/settings-center/plugin-manager/index.tsx +3 -0
|
@@ -8,12 +8,20 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import React from 'react';
|
|
11
|
-
import { render, screen } from '@testing-library/react';
|
|
11
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
12
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
12
13
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
13
14
|
|
|
14
|
-
const { allowMock, flowModelRendererSpy } = vi.hoisted(() => {
|
|
15
|
+
const { allowMock, appMock, flowModelRendererSpy } = vi.hoisted(() => {
|
|
15
16
|
return {
|
|
16
17
|
allowMock: vi.fn(),
|
|
18
|
+
appMock: {
|
|
19
|
+
current: {
|
|
20
|
+
router: {
|
|
21
|
+
getBasename: () => '/nocobase/v',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
17
25
|
flowModelRendererSpy: vi.fn(),
|
|
18
26
|
};
|
|
19
27
|
});
|
|
@@ -32,6 +40,12 @@ vi.mock('../HelpLite', () => {
|
|
|
32
40
|
};
|
|
33
41
|
});
|
|
34
42
|
|
|
43
|
+
vi.mock('../../../../hooks/useApp', () => {
|
|
44
|
+
return {
|
|
45
|
+
useApp: () => appMock.current,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
|
|
35
49
|
vi.mock('@nocobase/flow-engine', async (importOriginal) => {
|
|
36
50
|
const actual = await importOriginal<typeof import('@nocobase/flow-engine')>();
|
|
37
51
|
return {
|
|
@@ -63,10 +77,19 @@ const createAction = (options: Record<string, any>) => {
|
|
|
63
77
|
} as any;
|
|
64
78
|
};
|
|
65
79
|
|
|
80
|
+
const renderSettingsLabel = (label: React.ReactNode, pathname: string) => {
|
|
81
|
+
return render(<MemoryRouter initialEntries={[pathname]}>{label}</MemoryRouter>);
|
|
82
|
+
};
|
|
83
|
+
|
|
66
84
|
describe('TopbarActionsBar helpers', () => {
|
|
67
85
|
beforeEach(() => {
|
|
68
86
|
allowMock.mockReset();
|
|
69
87
|
flowModelRendererSpy.mockClear();
|
|
88
|
+
appMock.current = {
|
|
89
|
+
router: {
|
|
90
|
+
getBasename: () => '/nocobase/v',
|
|
91
|
+
},
|
|
92
|
+
};
|
|
70
93
|
});
|
|
71
94
|
|
|
72
95
|
afterEach(() => {
|
|
@@ -149,6 +172,147 @@ describe('TopbarActionsBar helpers', () => {
|
|
|
149
172
|
});
|
|
150
173
|
});
|
|
151
174
|
|
|
175
|
+
it('should open regular admin settings in a new tab outside admin runtime', () => {
|
|
176
|
+
const items = getTopbarPluginSettingsItems({
|
|
177
|
+
canManagePlugins: false,
|
|
178
|
+
t: (key) => key,
|
|
179
|
+
settings: [
|
|
180
|
+
{
|
|
181
|
+
key: 'system-settings',
|
|
182
|
+
name: 'system-settings',
|
|
183
|
+
title: 'System settings',
|
|
184
|
+
path: '/admin/settings/system-settings',
|
|
185
|
+
icon: null,
|
|
186
|
+
componentLoader: async () => null,
|
|
187
|
+
},
|
|
188
|
+
] as any,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
renderSettingsLabel((items as any[])[0].label, '/sales/p1');
|
|
192
|
+
|
|
193
|
+
const link = screen.getByRole('link', { name: 'System settings' });
|
|
194
|
+
expect(link).toHaveAttribute('href', '/nocobase/v/admin/settings/system-settings');
|
|
195
|
+
expect(link).toHaveAttribute('target', '_blank');
|
|
196
|
+
expect(link).toHaveAttribute('rel', expect.stringContaining('noopener'));
|
|
197
|
+
expect(link).toHaveAttribute('rel', expect.stringContaining('noreferrer'));
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('should open plugin manager in a new tab outside admin runtime', () => {
|
|
201
|
+
const items = getTopbarPluginSettingsItems({
|
|
202
|
+
canManagePlugins: true,
|
|
203
|
+
t: (key) => key,
|
|
204
|
+
settings: [
|
|
205
|
+
{
|
|
206
|
+
key: 'plugin-manager',
|
|
207
|
+
name: 'plugin-manager',
|
|
208
|
+
title: 'Plugin manager',
|
|
209
|
+
path: '/admin/settings/plugin-manager',
|
|
210
|
+
icon: null,
|
|
211
|
+
componentLoader: async () => null,
|
|
212
|
+
},
|
|
213
|
+
] as any,
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
renderSettingsLabel((items as any[])[0].label, '/sales/p1');
|
|
217
|
+
|
|
218
|
+
const link = screen.getByRole('link', { name: 'Plugin manager' });
|
|
219
|
+
expect(link).toHaveAttribute('href', '/nocobase/v/admin/settings/plugin-manager');
|
|
220
|
+
expect(link).toHaveAttribute('target', '_blank');
|
|
221
|
+
expect(link).toHaveAttribute('rel', expect.stringContaining('noopener'));
|
|
222
|
+
expect(link).toHaveAttribute('rel', expect.stringContaining('noreferrer'));
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('should keep regular admin settings as SPA links inside admin runtime', () => {
|
|
226
|
+
const items = getTopbarPluginSettingsItems({
|
|
227
|
+
canManagePlugins: false,
|
|
228
|
+
t: (key) => key,
|
|
229
|
+
settings: [
|
|
230
|
+
{
|
|
231
|
+
key: 'routes',
|
|
232
|
+
name: 'routes',
|
|
233
|
+
title: 'Routes',
|
|
234
|
+
path: '/admin/settings/routes',
|
|
235
|
+
icon: null,
|
|
236
|
+
componentLoader: async () => null,
|
|
237
|
+
},
|
|
238
|
+
] as any,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
renderSettingsLabel((items as any[])[0].label, '/admin/settings/routes');
|
|
242
|
+
|
|
243
|
+
const link = screen.getByRole('link', { name: 'Routes' });
|
|
244
|
+
expect(link).toHaveAttribute('href', '/admin/settings/routes');
|
|
245
|
+
expect(link).not.toHaveAttribute('target', '_blank');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('should not treat admin-like paths as admin runtime', () => {
|
|
249
|
+
const items = getTopbarPluginSettingsItems({
|
|
250
|
+
canManagePlugins: false,
|
|
251
|
+
t: (key) => key,
|
|
252
|
+
settings: [
|
|
253
|
+
{
|
|
254
|
+
key: 'system-settings',
|
|
255
|
+
name: 'system-settings',
|
|
256
|
+
title: 'System settings',
|
|
257
|
+
path: '/admin/settings/system-settings',
|
|
258
|
+
icon: null,
|
|
259
|
+
componentLoader: async () => null,
|
|
260
|
+
},
|
|
261
|
+
] as any,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
renderSettingsLabel((items as any[])[0].label, '/admin2/foo');
|
|
265
|
+
|
|
266
|
+
const link = screen.getByRole('link', { name: 'System settings' });
|
|
267
|
+
expect(link).toHaveAttribute('href', '/nocobase/v/admin/settings/system-settings');
|
|
268
|
+
expect(link).toHaveAttribute('target', '_blank');
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('should not duplicate the basename when building new-tab settings hrefs', () => {
|
|
272
|
+
const items = getTopbarPluginSettingsItems({
|
|
273
|
+
canManagePlugins: false,
|
|
274
|
+
t: (key) => key,
|
|
275
|
+
settings: [
|
|
276
|
+
{
|
|
277
|
+
key: 'system-settings',
|
|
278
|
+
name: 'system-settings',
|
|
279
|
+
title: 'System settings',
|
|
280
|
+
path: '/nocobase/v/admin/settings/system-settings',
|
|
281
|
+
icon: null,
|
|
282
|
+
componentLoader: async () => null,
|
|
283
|
+
},
|
|
284
|
+
] as any,
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
renderSettingsLabel((items as any[])[0].label, '/sales/p1');
|
|
288
|
+
|
|
289
|
+
const link = screen.getByRole('link', { name: 'System settings' });
|
|
290
|
+
expect(link).toHaveAttribute('href', '/nocobase/v/admin/settings/system-settings');
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('should keep external settings opening in a new tab', () => {
|
|
294
|
+
const openSpy = vi.spyOn(window, 'open').mockImplementation(() => null);
|
|
295
|
+
const items = getTopbarPluginSettingsItems({
|
|
296
|
+
canManagePlugins: false,
|
|
297
|
+
t: (key) => key,
|
|
298
|
+
settings: [
|
|
299
|
+
{
|
|
300
|
+
key: 'docs',
|
|
301
|
+
name: 'docs',
|
|
302
|
+
title: 'Docs',
|
|
303
|
+
link: 'https://www.nocobase.com/docs',
|
|
304
|
+
icon: null,
|
|
305
|
+
componentLoader: async () => null,
|
|
306
|
+
},
|
|
307
|
+
] as any,
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
renderSettingsLabel((items as any[])[0].label, '/sales/p1');
|
|
311
|
+
fireEvent.click(screen.getByText('Docs'));
|
|
312
|
+
|
|
313
|
+
expect(openSpy).toHaveBeenCalledWith('https://www.nocobase.com/docs', '_blank', 'noopener,noreferrer');
|
|
314
|
+
});
|
|
315
|
+
|
|
152
316
|
it('should return empty dropdown items when plugin manager and settings are both unavailable', () => {
|
|
153
317
|
const items = getTopbarPluginSettingsItems({
|
|
154
318
|
canManagePlugins: false,
|
|
@@ -52,6 +52,26 @@ describe('resolveAdminRouteRuntimeTarget', () => {
|
|
|
52
52
|
});
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
+
it('should resolve flowPage under a custom admin layout route path', () => {
|
|
56
|
+
expect(
|
|
57
|
+
resolveAdminRouteRuntimeTarget({
|
|
58
|
+
app,
|
|
59
|
+
layout: {
|
|
60
|
+
routePath: '/admin2',
|
|
61
|
+
},
|
|
62
|
+
route: {
|
|
63
|
+
type: NocoBaseDesktopRouteType.flowPage,
|
|
64
|
+
schemaUid: 'flow-page-1',
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
67
|
+
).toEqual({
|
|
68
|
+
runtimePath: '/nocobase/v2/admin2/flow-page-1',
|
|
69
|
+
navigationMode: 'spa',
|
|
70
|
+
isLegacy: false,
|
|
71
|
+
reason: 'ok',
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
55
75
|
it('should mark page unsupported in v2 admin runtime', () => {
|
|
56
76
|
expect(
|
|
57
77
|
resolveAdminRouteRuntimeTarget({
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { getModernClientPrefix, getV2EffectiveBasePath } from '../../../authRedirect';
|
|
11
11
|
import type { BaseApplication } from '../../../BaseApplication';
|
|
12
12
|
import { NocoBaseDesktopRouteType, type NocoBaseDesktopRoute } from '../../../flow-compat';
|
|
13
|
+
import type { LayoutDefinition } from '../../../layout-manager/types';
|
|
13
14
|
|
|
14
15
|
export type AdminRouteNavigationMode = 'spa' | 'document';
|
|
15
16
|
export type AdminRouteRuntimeTargetReason =
|
|
@@ -32,6 +33,8 @@ type LocationLike = {
|
|
|
32
33
|
hash?: string;
|
|
33
34
|
};
|
|
34
35
|
|
|
36
|
+
export type AdminLayoutRoutePathLike = Pick<LayoutDefinition, 'routePath'>;
|
|
37
|
+
|
|
35
38
|
type ResolveAdminRouteRuntimeTargetOptions = {
|
|
36
39
|
app: Pick<BaseApplication<any>, 'getPublicPath'> & {
|
|
37
40
|
router?: {
|
|
@@ -39,12 +42,14 @@ type ResolveAdminRouteRuntimeTargetOptions = {
|
|
|
39
42
|
};
|
|
40
43
|
};
|
|
41
44
|
route?: NocoBaseDesktopRoute;
|
|
45
|
+
layout?: AdminLayoutRoutePathLike;
|
|
42
46
|
location?: LocationLike;
|
|
43
47
|
preserveLocationState?: boolean;
|
|
44
48
|
log?: (message?: any, ...optionalParams: any[]) => void;
|
|
45
49
|
};
|
|
46
50
|
|
|
47
51
|
const LOG_PREFIX = '[NocoBase] Admin route runtime target:';
|
|
52
|
+
export const DEFAULT_ADMIN_LAYOUT_ROUTE_PATH = '/admin';
|
|
48
53
|
|
|
49
54
|
const EMPTY_TARGET: AdminRouteRuntimeTarget = {
|
|
50
55
|
runtimePath: null,
|
|
@@ -61,6 +66,25 @@ function normalizeRootRelativePath(pathname: string) {
|
|
|
61
66
|
return normalized;
|
|
62
67
|
}
|
|
63
68
|
|
|
69
|
+
export function getAdminLayoutRoutePath(layout?: AdminLayoutRoutePathLike | null) {
|
|
70
|
+
const routePath = typeof layout?.routePath === 'string' ? layout.routePath.trim() : '';
|
|
71
|
+
return routePath.startsWith('/') ? normalizeRootRelativePath(routePath) : DEFAULT_ADMIN_LAYOUT_ROUTE_PATH;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function joinAdminLayoutRoutePath(
|
|
75
|
+
layout: AdminLayoutRoutePathLike | null | undefined,
|
|
76
|
+
pathname?: string | number | null,
|
|
77
|
+
) {
|
|
78
|
+
const layoutRoutePath = getAdminLayoutRoutePath(layout);
|
|
79
|
+
const routePath = pathname == null ? '' : String(pathname).replace(/^\/+/, '');
|
|
80
|
+
|
|
81
|
+
if (!routePath) {
|
|
82
|
+
return layoutRoutePath;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return normalizeRootRelativePath(`${layoutRoutePath}/${routePath}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
64
88
|
function normalizePublicPath(value = '/') {
|
|
65
89
|
const normalized = normalizeRootRelativePath(value || '/');
|
|
66
90
|
return normalized.endsWith('/') ? normalized : `${normalized}/`;
|
|
@@ -104,8 +128,12 @@ function joinRootRelativePath(basePath: string, pathname: string) {
|
|
|
104
128
|
return normalizeRootRelativePath(`${normalizedBasePath}${normalizedPathname.slice(1)}`);
|
|
105
129
|
}
|
|
106
130
|
|
|
107
|
-
function getV2AdminPath(
|
|
108
|
-
|
|
131
|
+
function getV2AdminPath(
|
|
132
|
+
app: ResolveAdminRouteRuntimeTargetOptions['app'],
|
|
133
|
+
schemaUid: string,
|
|
134
|
+
layout?: AdminLayoutRoutePathLike,
|
|
135
|
+
) {
|
|
136
|
+
return joinRootRelativePath(getV2EffectiveBasePath(app), joinAdminLayoutRoutePath(layout, schemaUid));
|
|
109
137
|
}
|
|
110
138
|
|
|
111
139
|
function appendLocationState(pathname: string, location?: LocationLike) {
|
|
@@ -212,7 +240,7 @@ function resolvePageRuntimeTarget(
|
|
|
212
240
|
|
|
213
241
|
if (route.type === NocoBaseDesktopRouteType.flowPage) {
|
|
214
242
|
return {
|
|
215
|
-
runtimePath: getV2AdminPath(app, route.schemaUid),
|
|
243
|
+
runtimePath: getV2AdminPath(app, route.schemaUid, options.layout),
|
|
216
244
|
navigationMode: 'spa' as const,
|
|
217
245
|
isLegacy: false,
|
|
218
246
|
reason: 'ok' as const,
|
|
@@ -229,8 +257,8 @@ function resolvePageRuntimeTarget(
|
|
|
229
257
|
return {
|
|
230
258
|
runtimePath:
|
|
231
259
|
preserveLocationState && location
|
|
232
|
-
? appendLocationState(getV2AdminPath(app, route.schemaUid), location)
|
|
233
|
-
: getV2AdminPath(app, route.schemaUid),
|
|
260
|
+
? appendLocationState(getV2AdminPath(app, route.schemaUid, options.layout), location)
|
|
261
|
+
: getV2AdminPath(app, route.schemaUid, options.layout),
|
|
234
262
|
navigationMode: 'spa' as const,
|
|
235
263
|
isLegacy: false,
|
|
236
264
|
reason: 'ok' as const,
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
parseValueToPath,
|
|
19
19
|
isRunJSValue,
|
|
20
20
|
normalizeRunJSValue,
|
|
21
|
-
runjsWithSafeGlobals,
|
|
22
21
|
useFlowContext,
|
|
23
22
|
extractPropertyPath,
|
|
24
23
|
FlowModel,
|
|
@@ -240,7 +239,7 @@ export const DefaultValue = connect((props: Props) => {
|
|
|
240
239
|
if (isRunJSValue(out)) {
|
|
241
240
|
try {
|
|
242
241
|
const { code, version } = normalizeRunJSValue(out);
|
|
243
|
-
const ret = await
|
|
242
|
+
const ret = await model?.context?.runjs(code, undefined, { version });
|
|
244
243
|
out = ret?.success ? ret.value : undefined;
|
|
245
244
|
} catch {
|
|
246
245
|
out = undefined;
|