@nocobase/flow-engine 2.1.0-beta.10 → 2.1.0-beta.12
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/lib/components/FlowModelRenderer.d.ts +1 -1
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +3 -0
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +48 -9
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +19 -43
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +332 -296
- package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.d.ts +36 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.js +272 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.d.ts +30 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +247 -0
- package/lib/components/subModel/AddSubModelButton.js +11 -0
- package/lib/flowContext.js +27 -0
- package/lib/runjs-context/setup.js +1 -0
- package/lib/runjs-context/snippets/index.js +13 -2
- package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.js +50 -0
- package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.js +54 -0
- package/package.json +5 -4
- package/src/__tests__/flowContext.test.ts +65 -1
- package/src/__tests__/runjsContext.test.ts +3 -0
- package/src/__tests__/runjsContextRuntime.test.ts +2 -0
- package/src/__tests__/runjsSnippets.test.ts +21 -0
- package/src/components/FlowModelRenderer.tsx +3 -1
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +17 -7
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +63 -9
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +457 -440
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +95 -0
- package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +547 -0
- package/src/components/settings/wrappers/contextual/useFloatToolbarPortal.ts +358 -0
- package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +281 -0
- package/src/components/subModel/AddSubModelButton.tsx +15 -1
- package/src/flowContext.ts +30 -0
- package/src/runjs-context/setup.ts +1 -0
- package/src/runjs-context/snippets/index.ts +12 -1
- package/src/runjs-context/snippets/scene/detail/set-field-style.snippet.ts +30 -0
- package/src/runjs-context/snippets/scene/table/set-cell-style.snippet.ts +34 -0
package/src/flowContext.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { ISchema } from '@formily/json-schema';
|
|
|
11
11
|
import { observable } from '@formily/reactive';
|
|
12
12
|
import { APIClient, RequestOptions } from '@nocobase/sdk';
|
|
13
13
|
import type { Router } from '@remix-run/router';
|
|
14
|
+
import axios from 'axios';
|
|
14
15
|
import { MessageInstance } from 'antd/es/message/interface';
|
|
15
16
|
import * as antd from 'antd';
|
|
16
17
|
import type { HookAPI } from 'antd/es/modal/useModal';
|
|
@@ -58,6 +59,31 @@ import dayjs from 'dayjs';
|
|
|
58
59
|
import { externalReactRender, setupRunJSLibs } from './runjsLibs';
|
|
59
60
|
import { runjsImportAsync, runjsImportModule, runjsRequireAsync } from './utils/runjsModuleLoader';
|
|
60
61
|
|
|
62
|
+
function normalizePathname(pathname: string) {
|
|
63
|
+
return pathname.endsWith('/') ? pathname : `${pathname}/`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function shouldBypassApiClient(url: string, app?: { getApiUrl?: (pathname?: string) => string }) {
|
|
67
|
+
try {
|
|
68
|
+
const requestUrl = new URL(url);
|
|
69
|
+
if (!['http:', 'https:'].includes(requestUrl.protocol)) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (!app?.getApiUrl) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const apiUrl = new URL(app.getApiUrl());
|
|
78
|
+
const apiPath = normalizePathname(apiUrl.pathname);
|
|
79
|
+
const requestPath = normalizePathname(requestUrl.pathname);
|
|
80
|
+
|
|
81
|
+
return requestUrl.origin !== apiUrl.origin || !requestPath.startsWith(apiPath);
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
61
87
|
// Helper: detect a RecordRef-like object
|
|
62
88
|
function isRecordRefLike(val: any): boolean {
|
|
63
89
|
return !!(val && typeof val === 'object' && 'collection' in val && 'filterByTk' in val);
|
|
@@ -3024,6 +3050,10 @@ class BaseFlowEngineContext extends FlowContext {
|
|
|
3024
3050
|
return this.engine.getModel(modelName, searchInPreviousEngines);
|
|
3025
3051
|
});
|
|
3026
3052
|
this.defineMethod('request', (options: RequestOptions) => {
|
|
3053
|
+
const app = this.app as { getApiUrl?: (pathname?: string) => string } | undefined;
|
|
3054
|
+
if (typeof options?.url === 'string' && shouldBypassApiClient(options.url, app)) {
|
|
3055
|
+
return axios.request(options);
|
|
3056
|
+
}
|
|
3027
3057
|
return this.api.request(options);
|
|
3028
3058
|
});
|
|
3029
3059
|
this.defineMethod(
|
|
@@ -47,6 +47,7 @@ export async function setupRunJSContexts() {
|
|
|
47
47
|
RunJSContextRegistry.register(version, 'JSFieldModel', JSFieldRunJSContext, { scenes: ['detail'] });
|
|
48
48
|
RunJSContextRegistry.register(version, 'JSEditableFieldModel', JSEditableFieldRunJSContext, { scenes: ['form'] });
|
|
49
49
|
RunJSContextRegistry.register(version, 'JSItemModel', JSItemRunJSContext, { scenes: ['form'] });
|
|
50
|
+
RunJSContextRegistry.register(version, 'JSItemActionModel', JSItemRunJSContext, { scenes: ['table'] });
|
|
50
51
|
RunJSContextRegistry.register(version, 'JSColumnModel', JSColumnRunJSContext, { scenes: ['table'] });
|
|
51
52
|
RunJSContextRegistry.register(version, 'FormJSFieldItemModel', FormJSFieldItemRunJSContext, { scenes: ['form'] });
|
|
52
53
|
RunJSContextRegistry.register(version, 'JSRecordActionModel', JSRecordActionRunJSContext, { scenes: ['table'] });
|
|
@@ -49,6 +49,7 @@ const snippets: Record<string, RunJSSnippetLoader | undefined> = {
|
|
|
49
49
|
'scene/detail/status-tag': () => import('./scene/detail/status-tag.snippet'),
|
|
50
50
|
'scene/detail/relative-time': () => import('./scene/detail/relative-time.snippet'),
|
|
51
51
|
'scene/detail/percentage-bar': () => import('./scene/detail/percentage-bar.snippet'),
|
|
52
|
+
'scene/detail/set-field-style': () => import('./scene/detail/set-field-style.snippet'),
|
|
52
53
|
// scene/form
|
|
53
54
|
'scene/form/render-basic': () => import('./scene/form/render-basic.snippet'),
|
|
54
55
|
'scene/form/set-field-value': () => import('./scene/form/set-field-value.snippet'),
|
|
@@ -67,6 +68,7 @@ const snippets: Record<string, RunJSSnippetLoader | undefined> = {
|
|
|
67
68
|
'scene/table/iterate-selected-rows': () => import('./scene/table/iterate-selected-rows.snippet'),
|
|
68
69
|
'scene/table/destroy-selected': () => import('./scene/table/destroy-selected.snippet'),
|
|
69
70
|
'scene/table/export-selected-json': () => import('./scene/table/export-selected-json.snippet'),
|
|
71
|
+
'scene/table/set-cell-style': () => import('./scene/table/set-cell-style.snippet'),
|
|
70
72
|
};
|
|
71
73
|
|
|
72
74
|
export default snippets;
|
|
@@ -125,10 +127,19 @@ function normalizeScenes(def: any, key: string): string[] {
|
|
|
125
127
|
return [];
|
|
126
128
|
}
|
|
127
129
|
|
|
130
|
+
function normalizeSceneGroup(scene: string): string {
|
|
131
|
+
const mapping: Record<string, string> = {
|
|
132
|
+
detailFieldEvent: 'detail',
|
|
133
|
+
tableFieldEvent: 'table',
|
|
134
|
+
formFieldEvent: 'form',
|
|
135
|
+
};
|
|
136
|
+
return mapping[scene] || scene;
|
|
137
|
+
}
|
|
138
|
+
|
|
128
139
|
function computeGroups(def: any, key: string): string[] {
|
|
129
140
|
const scenes = normalizeScenes(def, key);
|
|
130
141
|
if (scenes.length) {
|
|
131
|
-
return scenes.map((scene) => `scene/${scene}`);
|
|
142
|
+
return Array.from(new Set(scenes.map((scene) => `scene/${normalizeSceneGroup(scene)}`)));
|
|
132
143
|
}
|
|
133
144
|
const parts = key.split('/');
|
|
134
145
|
if (!parts.length) return [];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { SnippetModule } from '../../types';
|
|
11
|
+
const snippet: SnippetModule = {
|
|
12
|
+
contexts: ['*'],
|
|
13
|
+
scenes: ['detailFieldEvent', 'formFieldEvent'],
|
|
14
|
+
prefix: 'sn-item-style',
|
|
15
|
+
label: 'Set form item/details item style',
|
|
16
|
+
description: 'Customize form item and details item container styles',
|
|
17
|
+
locales: {
|
|
18
|
+
'zh-CN': {
|
|
19
|
+
label: '设置表单项/详情项样式',
|
|
20
|
+
description: '自定义表单项和详情项容器样式',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
content: `
|
|
24
|
+
ctx.model.props.style = {
|
|
25
|
+
background: 'red',
|
|
26
|
+
};
|
|
27
|
+
`,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default snippet;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { SnippetModule } from '../../types';
|
|
11
|
+
const snippet: SnippetModule = {
|
|
12
|
+
contexts: ['*'],
|
|
13
|
+
scenes: ['tableFieldEvent'],
|
|
14
|
+
prefix: 'sn-table-cell-style',
|
|
15
|
+
label: 'Set table cell style',
|
|
16
|
+
description: 'Customize table field cell styles with onCell',
|
|
17
|
+
locales: {
|
|
18
|
+
'zh-CN': {
|
|
19
|
+
label: '表格字段样式设置',
|
|
20
|
+
description: '通过 onCell 自定义表格字段单元格样式',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
content: `
|
|
24
|
+
ctx.model.props.onCell = (record, rowIndex) => {
|
|
25
|
+
return {
|
|
26
|
+
style: {
|
|
27
|
+
background: 'red',
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
`,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default snippet;
|