@nocobase/flow-engine 2.1.0-alpha.4 → 2.1.0-alpha.40
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/LICENSE +201 -661
- package/README.md +79 -10
- package/lib/JSRunner.d.ts +10 -1
- package/lib/JSRunner.js +50 -5
- package/lib/ViewScopedFlowEngine.js +5 -1
- package/lib/components/FieldModelRenderer.js +2 -2
- package/lib/components/FlowModelRenderer.d.ts +3 -1
- package/lib/components/FlowModelRenderer.js +12 -6
- package/lib/components/FormItem.d.ts +6 -0
- package/lib/components/FormItem.js +11 -3
- package/lib/components/MobilePopup.js +6 -5
- package/lib/components/dnd/gridDragPlanner.d.ts +59 -2
- package/lib/components/dnd/gridDragPlanner.js +613 -21
- package/lib/components/dnd/index.d.ts +31 -2
- package/lib/components/dnd/index.js +244 -23
- package/lib/components/settings/wrappers/component/SelectWithTitle.d.ts +2 -1
- package/lib/components/settings/wrappers/component/SelectWithTitle.js +14 -12
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +3 -0
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +68 -10
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +23 -43
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +352 -295
- package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +16 -2
- package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.d.ts +36 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.js +274 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.d.ts +30 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +315 -0
- package/lib/components/subModel/AddSubModelButton.js +27 -1
- package/lib/components/subModel/LazyDropdown.js +96 -39
- package/lib/components/subModel/index.d.ts +1 -0
- package/lib/components/subModel/index.js +19 -0
- package/lib/components/subModel/utils.d.ts +1 -1
- package/lib/components/subModel/utils.js +9 -3
- package/lib/components/variables/VariableHybridInput.d.ts +27 -0
- package/lib/components/variables/VariableHybridInput.js +499 -0
- package/lib/components/variables/index.d.ts +2 -0
- package/lib/components/variables/index.js +3 -0
- package/lib/data-source/index.d.ts +75 -0
- package/lib/data-source/index.js +247 -5
- package/lib/executor/FlowExecutor.js +32 -9
- package/lib/flow-registry/DetachedFlowRegistry.d.ts +21 -0
- package/lib/flow-registry/DetachedFlowRegistry.js +80 -0
- package/lib/flow-registry/index.d.ts +1 -0
- package/lib/flow-registry/index.js +3 -1
- package/lib/flowContext.d.ts +3 -0
- package/lib/flowContext.js +43 -1
- package/lib/flowEngine.d.ts +151 -1
- package/lib/flowEngine.js +389 -15
- package/lib/flowI18n.js +2 -1
- package/lib/flowSettings.d.ts +14 -6
- package/lib/flowSettings.js +34 -6
- package/lib/index.d.ts +2 -0
- package/lib/index.js +7 -0
- package/lib/lazy-helper.d.ts +14 -0
- package/lib/lazy-helper.js +71 -0
- package/lib/locale/en-US.json +1 -0
- package/lib/locale/index.d.ts +2 -0
- package/lib/locale/zh-CN.json +1 -0
- package/lib/models/DisplayItemModel.d.ts +1 -1
- package/lib/models/EditableItemModel.d.ts +1 -1
- package/lib/models/FilterableItemModel.d.ts +1 -1
- package/lib/models/flowModel.d.ts +13 -10
- package/lib/models/flowModel.js +78 -18
- package/lib/provider.js +38 -23
- package/lib/reactive/observer.js +46 -16
- package/lib/runjs-context/registry.d.ts +1 -1
- package/lib/runjs-context/setup.js +20 -12
- 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/lib/scheduler/ModelOperationScheduler.d.ts +5 -1
- package/lib/scheduler/ModelOperationScheduler.js +3 -2
- package/lib/types.d.ts +50 -2
- package/lib/types.js +1 -0
- package/lib/utils/createCollectionContextMeta.js +6 -2
- package/lib/utils/index.d.ts +3 -2
- package/lib/utils/index.js +7 -0
- package/lib/utils/parsePathnameToViewParams.js +1 -1
- package/lib/utils/randomId.d.ts +39 -0
- package/lib/utils/randomId.js +45 -0
- package/lib/utils/runjsTemplateCompat.js +1 -1
- package/lib/utils/runjsValue.js +41 -11
- package/lib/utils/schema-utils.d.ts +7 -1
- package/lib/utils/schema-utils.js +19 -0
- package/lib/views/FlowView.d.ts +7 -1
- package/lib/views/FlowView.js +11 -1
- package/lib/views/PageComponent.js +8 -6
- package/lib/views/ViewNavigation.js +6 -2
- package/lib/views/runViewBeforeClose.d.ts +10 -0
- package/lib/views/runViewBeforeClose.js +45 -0
- package/lib/views/useDialog.d.ts +2 -1
- package/lib/views/useDialog.js +20 -3
- package/lib/views/useDrawer.d.ts +2 -1
- package/lib/views/useDrawer.js +20 -3
- package/lib/views/usePage.d.ts +5 -11
- package/lib/views/usePage.js +302 -144
- package/package.json +6 -5
- package/src/JSRunner.ts +68 -4
- package/src/ViewScopedFlowEngine.ts +4 -0
- package/src/__tests__/JSRunner.test.ts +27 -1
- package/src/__tests__/flow-engine.test.ts +166 -0
- package/src/__tests__/flowContext.test.ts +82 -1
- package/src/__tests__/flowEngine.modelLoaders.test.ts +245 -0
- package/src/__tests__/flowSettings.test.ts +94 -15
- package/src/__tests__/objectVariable.test.ts +24 -0
- package/src/__tests__/provider.test.tsx +24 -2
- package/src/__tests__/renderHiddenInConfig.test.tsx +6 -6
- package/src/__tests__/runjsContext.test.ts +16 -0
- package/src/__tests__/runjsContextRuntime.test.ts +2 -0
- package/src/__tests__/runjsPreprocessDefault.test.ts +23 -0
- package/src/__tests__/runjsSnippets.test.ts +21 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +3 -3
- package/src/components/FieldModelRenderer.tsx +2 -1
- package/src/components/FlowModelRenderer.tsx +18 -6
- package/src/components/FormItem.tsx +7 -1
- package/src/components/MobilePopup.tsx +4 -2
- package/src/components/__tests__/FlowModelRenderer.test.tsx +65 -2
- package/src/components/__tests__/FormItem.test.tsx +25 -0
- package/src/components/__tests__/dnd.test.ts +44 -0
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +20 -10
- package/src/components/__tests__/gridDragPlanner.test.ts +558 -3
- package/src/components/dnd/__tests__/DndProvider.test.tsx +98 -0
- package/src/components/dnd/gridDragPlanner.ts +758 -19
- package/src/components/dnd/index.tsx +305 -28
- package/src/components/settings/wrappers/component/SelectWithTitle.tsx +21 -9
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +88 -10
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +487 -440
- package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +18 -2
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +189 -3
- package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +778 -0
- package/src/components/settings/wrappers/contextual/useFloatToolbarPortal.ts +360 -0
- package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +361 -0
- package/src/components/subModel/AddSubModelButton.tsx +32 -2
- package/src/components/subModel/LazyDropdown.tsx +107 -43
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +319 -36
- package/src/components/subModel/__tests__/utils.test.ts +24 -0
- package/src/components/subModel/index.ts +1 -0
- package/src/components/subModel/utils.ts +7 -1
- package/src/components/variables/VariableHybridInput.tsx +531 -0
- package/src/components/variables/index.ts +2 -0
- package/src/data-source/__tests__/collection.test.ts +41 -2
- package/src/data-source/__tests__/index.test.ts +68 -1
- package/src/data-source/index.ts +304 -6
- package/src/executor/FlowExecutor.ts +35 -10
- package/src/executor/__tests__/flowExecutor.test.ts +57 -0
- package/src/flow-registry/DetachedFlowRegistry.ts +46 -0
- package/src/flow-registry/__tests__/detachedFlowRegistry.test.ts +47 -0
- package/src/flow-registry/index.ts +1 -0
- package/src/flowContext.ts +47 -3
- package/src/flowEngine.ts +445 -11
- package/src/flowI18n.ts +2 -1
- package/src/flowSettings.ts +40 -6
- package/src/index.ts +2 -0
- package/src/lazy-helper.tsx +57 -0
- package/src/locale/en-US.json +1 -0
- package/src/locale/zh-CN.json +1 -0
- package/src/models/DisplayItemModel.tsx +1 -1
- package/src/models/EditableItemModel.tsx +1 -1
- package/src/models/FilterableItemModel.tsx +1 -1
- package/src/models/__tests__/dispatchEvent.when.test.ts +214 -0
- package/src/models/__tests__/flowModel.test.ts +47 -3
- package/src/models/flowModel.tsx +119 -33
- package/src/provider.tsx +41 -25
- package/src/reactive/__tests__/observer.test.tsx +82 -0
- package/src/reactive/observer.tsx +87 -25
- package/src/runjs-context/registry.ts +1 -1
- package/src/runjs-context/setup.ts +22 -12
- 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/scheduler/ModelOperationScheduler.ts +14 -3
- package/src/types.ts +62 -0
- package/src/utils/__tests__/createCollectionContextMeta.test.ts +48 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +7 -0
- package/src/utils/__tests__/runjsValue.test.ts +11 -0
- package/src/utils/__tests__/utils.test.ts +62 -0
- package/src/utils/createCollectionContextMeta.ts +6 -2
- package/src/utils/index.ts +5 -1
- package/src/utils/parsePathnameToViewParams.ts +2 -2
- package/src/utils/randomId.ts +48 -0
- package/src/utils/runjsTemplateCompat.ts +1 -1
- package/src/utils/runjsValue.ts +50 -11
- package/src/utils/schema-utils.ts +30 -1
- package/src/views/FlowView.tsx +22 -2
- package/src/views/PageComponent.tsx +7 -4
- package/src/views/ViewNavigation.ts +6 -2
- package/src/views/__tests__/FlowView.usePage.test.tsx +243 -3
- package/src/views/__tests__/runViewBeforeClose.test.ts +30 -0
- package/src/views/__tests__/useDialog.closeDestroy.test.tsx +13 -12
- package/src/views/runViewBeforeClose.ts +19 -0
- package/src/views/useDialog.tsx +25 -3
- package/src/views/useDrawer.tsx +25 -3
- package/src/views/usePage.tsx +365 -179
|
@@ -0,0 +1,47 @@
|
|
|
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 { describe, expect, test } from 'vitest';
|
|
11
|
+
import { DetachedFlowRegistry, replaceFlowRegistry, serializeFlowRegistry } from '../DetachedFlowRegistry';
|
|
12
|
+
|
|
13
|
+
describe('DetachedFlowRegistry', () => {
|
|
14
|
+
test('keeps flow edits detached and can replace another registry', () => {
|
|
15
|
+
const source = {
|
|
16
|
+
flow1: {
|
|
17
|
+
title: 'Flow 1',
|
|
18
|
+
steps: {
|
|
19
|
+
step1: { title: 'Step 1' } as any,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const registry = new DetachedFlowRegistry(source);
|
|
24
|
+
|
|
25
|
+
source.flow1.title = 'Changed outside';
|
|
26
|
+
expect(registry.getFlow('flow1')?.title).toBe('Flow 1');
|
|
27
|
+
|
|
28
|
+
const flow = registry.getFlow('flow1');
|
|
29
|
+
expect(flow).toBeDefined();
|
|
30
|
+
if (!flow) {
|
|
31
|
+
throw new Error('flow1 should exist');
|
|
32
|
+
}
|
|
33
|
+
flow.title = 'Draft title';
|
|
34
|
+
const serialized = serializeFlowRegistry(registry);
|
|
35
|
+
serialized.flow1.title = 'Changed serialized';
|
|
36
|
+
expect(registry.getFlow('flow1')?.title).toBe('Draft title');
|
|
37
|
+
|
|
38
|
+
const target = new DetachedFlowRegistry({ stale: { title: 'Stale', steps: {} } });
|
|
39
|
+
replaceFlowRegistry(target, serializeFlowRegistry(registry));
|
|
40
|
+
|
|
41
|
+
expect(target.hasFlow('stale')).toBe(false);
|
|
42
|
+
expect(target.getFlow('flow1')?.title).toBe('Draft title');
|
|
43
|
+
|
|
44
|
+
target.destroyFlow('flow1');
|
|
45
|
+
expect(target.hasFlow('flow1')).toBe(false);
|
|
46
|
+
});
|
|
47
|
+
});
|
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';
|
|
@@ -27,7 +28,7 @@ import { ContextPathProxy } from './ContextPathProxy';
|
|
|
27
28
|
import { DataSource, DataSourceManager } from './data-source';
|
|
28
29
|
import { FlowEngine } from './flowEngine';
|
|
29
30
|
import { FlowI18n } from './flowI18n';
|
|
30
|
-
import { JSRunner, JSRunnerOptions } from './JSRunner';
|
|
31
|
+
import { JSRunner, JSRunnerOptions, shouldPreprocessRunJSTemplates } from './JSRunner';
|
|
31
32
|
import type { FlowModel } from './models/flowModel';
|
|
32
33
|
import type { ForkFlowModel } from './models/forkFlowModel';
|
|
33
34
|
import { FlowResource, FlowSQLRepository } from './resources';
|
|
@@ -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);
|
|
@@ -2980,8 +3006,10 @@ export class FlowContext {
|
|
|
2980
3006
|
}
|
|
2981
3007
|
|
|
2982
3008
|
class BaseFlowEngineContext extends FlowContext {
|
|
3009
|
+
declare t: (key: any, options?: any) => string;
|
|
2983
3010
|
declare router: Router;
|
|
2984
3011
|
declare dataSourceManager: DataSourceManager;
|
|
3012
|
+
declare isDarkTheme: boolean;
|
|
2985
3013
|
declare requireAsync: (url: string) => Promise<any>;
|
|
2986
3014
|
declare importAsync: (url: string) => Promise<any>;
|
|
2987
3015
|
declare createJSRunner: (options?: JSRunnerOptions) => Promise<JSRunner>;
|
|
@@ -3008,6 +3036,7 @@ class BaseFlowEngineContext extends FlowContext {
|
|
|
3008
3036
|
declare runAction: (actionName: string, params?: Record<string, any>) => Promise<any> | any;
|
|
3009
3037
|
declare engine: FlowEngine;
|
|
3010
3038
|
declare api: APIClient;
|
|
3039
|
+
declare locale: string;
|
|
3011
3040
|
declare viewer: FlowViewer;
|
|
3012
3041
|
declare view: FlowView;
|
|
3013
3042
|
declare modal: HookAPI;
|
|
@@ -3024,6 +3053,10 @@ class BaseFlowEngineContext extends FlowContext {
|
|
|
3024
3053
|
return this.engine.getModel(modelName, searchInPreviousEngines);
|
|
3025
3054
|
});
|
|
3026
3055
|
this.defineMethod('request', (options: RequestOptions) => {
|
|
3056
|
+
const app = this.app as { getApiUrl?: (pathname?: string) => string } | undefined;
|
|
3057
|
+
if (typeof options?.url === 'string' && shouldBypassApiClient(options.url, app)) {
|
|
3058
|
+
return axios.request(options);
|
|
3059
|
+
}
|
|
3027
3060
|
return this.api.request(options);
|
|
3028
3061
|
});
|
|
3029
3062
|
this.defineMethod(
|
|
@@ -3035,8 +3068,10 @@ class BaseFlowEngineContext extends FlowContext {
|
|
|
3035
3068
|
...(runnerOptions || {}),
|
|
3036
3069
|
globals: mergedGlobals,
|
|
3037
3070
|
});
|
|
3038
|
-
|
|
3039
|
-
|
|
3071
|
+
const shouldPreprocessTemplates = shouldPreprocessRunJSTemplates({
|
|
3072
|
+
version: runnerOptions?.version,
|
|
3073
|
+
preprocessTemplates,
|
|
3074
|
+
});
|
|
3040
3075
|
const jsCode = await prepareRunJsCode(String(code ?? ''), { preprocessTemplates: shouldPreprocessTemplates });
|
|
3041
3076
|
return runner.run(jsCode);
|
|
3042
3077
|
},
|
|
@@ -3112,6 +3147,15 @@ export class FlowEngineContext extends BaseFlowEngineContext {
|
|
|
3112
3147
|
this.defineMethod('t', (keyOrTemplate: string, options?: any) => {
|
|
3113
3148
|
return i18n.translate(keyOrTemplate, options);
|
|
3114
3149
|
});
|
|
3150
|
+
this.defineProperty('locale', {
|
|
3151
|
+
get: () => this.api?.auth?.locale || this.i18n?.language,
|
|
3152
|
+
cache: false,
|
|
3153
|
+
meta: Object.assign(() => ({ type: 'string', title: this.t('Current language'), sort: 970 }), {
|
|
3154
|
+
title: escapeT('Current language'),
|
|
3155
|
+
sort: 970,
|
|
3156
|
+
hasChildren: false,
|
|
3157
|
+
}),
|
|
3158
|
+
});
|
|
3115
3159
|
this.defineMethod('renderJson', function (template: any) {
|
|
3116
3160
|
return this.resolveJsonTemplate(template);
|
|
3117
3161
|
});
|