@nocobase/flow-engine 2.1.8 → 2.1.10
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/flowContext.js
CHANGED
|
@@ -2294,6 +2294,36 @@ const _BaseFlowModelContext = class _BaseFlowModelContext extends BaseFlowEngine
|
|
|
2294
2294
|
};
|
|
2295
2295
|
__name(_BaseFlowModelContext, "BaseFlowModelContext");
|
|
2296
2296
|
let BaseFlowModelContext = _BaseFlowModelContext;
|
|
2297
|
+
const OPEN_VIEW_INHERITED_INPUT_ARG_KEYS = [
|
|
2298
|
+
"dataSourceKey",
|
|
2299
|
+
"collectionName",
|
|
2300
|
+
"associationName",
|
|
2301
|
+
"filterByTk",
|
|
2302
|
+
"sourceId",
|
|
2303
|
+
"tabUid"
|
|
2304
|
+
];
|
|
2305
|
+
function pickDefinedKeys(source, keys) {
|
|
2306
|
+
const res = {};
|
|
2307
|
+
for (const key of keys) {
|
|
2308
|
+
if (typeof (source == null ? void 0 : source[key]) !== "undefined") {
|
|
2309
|
+
res[key] = source[key];
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
return res;
|
|
2313
|
+
}
|
|
2314
|
+
__name(pickDefinedKeys, "pickDefinedKeys");
|
|
2315
|
+
function pickDefinedOpenViewInputArgs(source) {
|
|
2316
|
+
return pickDefinedKeys(source, OPEN_VIEW_INHERITED_INPUT_ARG_KEYS);
|
|
2317
|
+
}
|
|
2318
|
+
__name(pickDefinedOpenViewInputArgs, "pickDefinedOpenViewInputArgs");
|
|
2319
|
+
function applyDefinedDefaults(target, defaults) {
|
|
2320
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
2321
|
+
if (typeof target[key] === "undefined") {
|
|
2322
|
+
target[key] = value;
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
__name(applyDefinedDefaults, "applyDefinedDefaults");
|
|
2297
2327
|
const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContext {
|
|
2298
2328
|
// public dataSourceManager: DataSourceManager;
|
|
2299
2329
|
constructor(engine) {
|
|
@@ -2791,23 +2821,19 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2791
2821
|
}
|
|
2792
2822
|
});
|
|
2793
2823
|
this.defineMethod("openView", async function(uid, options) {
|
|
2794
|
-
var _a, _b, _c, _d
|
|
2795
|
-
const
|
|
2824
|
+
var _a, _b, _c, _d;
|
|
2825
|
+
const inheritedInputArgs = {
|
|
2826
|
+
...typeof ((_a = this.model) == null ? void 0 : _a["getInputArgs"]) === "function" ? pickDefinedOpenViewInputArgs(this.model["getInputArgs"]()) : {},
|
|
2827
|
+
...pickDefinedOpenViewInputArgs(this.inputArgs)
|
|
2828
|
+
};
|
|
2829
|
+
const opts = { ...options || {} };
|
|
2830
|
+
applyDefinedDefaults(opts, inheritedInputArgs);
|
|
2796
2831
|
if (opts.defineProperties || opts.defineMethods) {
|
|
2797
2832
|
opts.navigation = false;
|
|
2798
2833
|
}
|
|
2799
2834
|
let model2 = null;
|
|
2800
2835
|
model2 = await this.engine.loadModel({ uid });
|
|
2801
2836
|
if (!model2) {
|
|
2802
|
-
const pickDefined = /* @__PURE__ */ __name((src, keys) => {
|
|
2803
|
-
const res = {};
|
|
2804
|
-
for (const k of keys) {
|
|
2805
|
-
if (typeof (src == null ? void 0 : src[k]) !== "undefined") {
|
|
2806
|
-
res[k] = src[k];
|
|
2807
|
-
}
|
|
2808
|
-
}
|
|
2809
|
-
return res;
|
|
2810
|
-
}, "pickDefined");
|
|
2811
2837
|
model2 = this.engine.createModel({
|
|
2812
2838
|
uid,
|
|
2813
2839
|
// 注意: 新建的 model 应该使用 ${parentModel.uid}-xxx 形式的 uid
|
|
@@ -2819,7 +2845,7 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2819
2845
|
popupSettings: {
|
|
2820
2846
|
openView: {
|
|
2821
2847
|
// 仅在创建时持久化一份默认配置;运行时以本次 opts 为准,避免多个 opener 互相覆盖。
|
|
2822
|
-
...
|
|
2848
|
+
...pickDefinedKeys(opts, ["dataSourceKey", "collectionName", "associationName", "mode", "size"])
|
|
2823
2849
|
}
|
|
2824
2850
|
}
|
|
2825
2851
|
}
|
|
@@ -2827,12 +2853,10 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2827
2853
|
await model2.save();
|
|
2828
2854
|
}
|
|
2829
2855
|
model2.setParent(this.model);
|
|
2830
|
-
const viewUid = (opts == null ? void 0 : opts.routeViewUid) ?? (opts == null ? void 0 : opts.viewUid) ?? (((
|
|
2856
|
+
const viewUid = (opts == null ? void 0 : opts.routeViewUid) ?? (opts == null ? void 0 : opts.viewUid) ?? (((_c = (_b = model2.stepParams) == null ? void 0 : _b.popupSettings) == null ? void 0 : _c.openView) ? model2.uid : this.model.uid);
|
|
2831
2857
|
const parentView = this.view;
|
|
2832
2858
|
const pendingType = (opts == null ? void 0 : opts.isMobileLayout) ? "embed" : (opts == null ? void 0 : opts.mode) || "drawer";
|
|
2833
2859
|
const pendingInputArgs = { ...opts, viewUid, navigation: opts.navigation };
|
|
2834
|
-
pendingInputArgs.filterByTk = pendingInputArgs.filterByTk || ((_c = this.inputArgs) == null ? void 0 : _c.filterByTk);
|
|
2835
|
-
pendingInputArgs.sourceId = pendingInputArgs.sourceId || ((_d = this.inputArgs) == null ? void 0 : _d.sourceId);
|
|
2836
2860
|
const pendingView = {
|
|
2837
2861
|
type: pendingType,
|
|
2838
2862
|
inputArgs: pendingInputArgs,
|
|
@@ -2841,7 +2865,7 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2841
2865
|
engineCtx: this.engine.context
|
|
2842
2866
|
};
|
|
2843
2867
|
model2.context.defineProperty("view", { value: pendingView });
|
|
2844
|
-
const popupFlow = (
|
|
2868
|
+
const popupFlow = (_d = model2.getFlow) == null ? void 0 : _d.call(model2, "popupSettings");
|
|
2845
2869
|
const on = popupFlow == null ? void 0 : popupFlow.on;
|
|
2846
2870
|
let openEventName = "click";
|
|
2847
2871
|
if (typeof on === "string" && on) {
|
|
@@ -2849,17 +2873,10 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2849
2873
|
} else if (on && typeof on === "object" && typeof on.eventName === "string" && on.eventName) {
|
|
2850
2874
|
openEventName = on.eventName;
|
|
2851
2875
|
}
|
|
2852
|
-
await model2.dispatchEvent(
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
// ...this.model?.['getInputArgs']?.(), // 避免部分关系字段信息丢失, 仿照 ClickableCollectionField 做法
|
|
2857
|
-
...opts
|
|
2858
|
-
},
|
|
2859
|
-
{
|
|
2860
|
-
debounce: true
|
|
2861
|
-
}
|
|
2862
|
-
);
|
|
2876
|
+
await model2.dispatchEvent(openEventName, {
|
|
2877
|
+
// navigation: false, // TODO: 路由模式有bug,不支持多层同样viewId的弹窗,因此这里默认先用false
|
|
2878
|
+
...opts
|
|
2879
|
+
});
|
|
2863
2880
|
});
|
|
2864
2881
|
this.defineMethod("getEvents", function() {
|
|
2865
2882
|
return this.model.getEvents();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/flow-engine",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A standalone flow engine for NocoBase, managing workflows, models, and actions.",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@formily/antd-v5": "1.x",
|
|
10
10
|
"@formily/reactive": "2.x",
|
|
11
|
-
"@nocobase/sdk": "2.1.
|
|
12
|
-
"@nocobase/shared": "2.1.
|
|
11
|
+
"@nocobase/sdk": "2.1.10",
|
|
12
|
+
"@nocobase/shared": "2.1.10",
|
|
13
13
|
"ahooks": "^3.7.2",
|
|
14
14
|
"axios": "^1.7.0",
|
|
15
15
|
"dayjs": "^1.11.9",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
],
|
|
38
38
|
"author": "NocoBase Team",
|
|
39
39
|
"license": "Apache-2.0",
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "65d5bc38d72d5a6fca8bcf9798a0b976e382cac9"
|
|
41
41
|
}
|
|
@@ -104,4 +104,32 @@ describe('FlowModelContext.openView - navigation enforcement', () => {
|
|
|
104
104
|
expect(child.dispatchEvent).toHaveBeenCalledTimes(1);
|
|
105
105
|
expect(child.dispatchEvent.mock.calls[0][0]).toBe('click');
|
|
106
106
|
});
|
|
107
|
+
|
|
108
|
+
it('inherits current model input args when opening an external popup', async () => {
|
|
109
|
+
const { parent, child } = setup();
|
|
110
|
+
parent['getInputArgs'] = vi.fn(() => ({
|
|
111
|
+
filterByTk: 2,
|
|
112
|
+
sourceId: 10,
|
|
113
|
+
defaultInputKeys: ['filterByTk', 'sourceId'],
|
|
114
|
+
}));
|
|
115
|
+
|
|
116
|
+
await (parent.context as any).openView('child-uid', { mode: 'dialog' });
|
|
117
|
+
|
|
118
|
+
expect(child.dispatchEvent).toHaveBeenCalledTimes(1);
|
|
119
|
+
expect(child.dispatchEvent.mock.calls[0][1]).toMatchObject({
|
|
120
|
+
mode: 'dialog',
|
|
121
|
+
filterByTk: 2,
|
|
122
|
+
sourceId: 10,
|
|
123
|
+
});
|
|
124
|
+
expect(child.dispatchEvent.mock.calls[0][1]).not.toHaveProperty('defaultInputKeys');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('does not debounce external popup dispatches', async () => {
|
|
128
|
+
const { parent, child } = setup();
|
|
129
|
+
|
|
130
|
+
await (parent.context as any).openView('child-uid', { mode: 'dialog', filterByTk: 1 });
|
|
131
|
+
|
|
132
|
+
expect(child.dispatchEvent).toHaveBeenCalledTimes(1);
|
|
133
|
+
expect(child.dispatchEvent.mock.calls[0][2]).toBeUndefined();
|
|
134
|
+
});
|
|
107
135
|
});
|
package/src/flowContext.ts
CHANGED
|
@@ -3139,6 +3139,37 @@ class BaseFlowModelContext extends BaseFlowEngineContext {
|
|
|
3139
3139
|
declare makeResource: <T extends FlowResource = FlowResource>(resourceType: ResourceType<T>) => T;
|
|
3140
3140
|
}
|
|
3141
3141
|
|
|
3142
|
+
const OPEN_VIEW_INHERITED_INPUT_ARG_KEYS = [
|
|
3143
|
+
'dataSourceKey',
|
|
3144
|
+
'collectionName',
|
|
3145
|
+
'associationName',
|
|
3146
|
+
'filterByTk',
|
|
3147
|
+
'sourceId',
|
|
3148
|
+
'tabUid',
|
|
3149
|
+
];
|
|
3150
|
+
|
|
3151
|
+
function pickDefinedKeys(source: Record<string, unknown> | null | undefined, keys: string[]) {
|
|
3152
|
+
const res: Record<string, unknown> = {};
|
|
3153
|
+
for (const key of keys) {
|
|
3154
|
+
if (typeof source?.[key] !== 'undefined') {
|
|
3155
|
+
res[key] = source[key];
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
return res;
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
function pickDefinedOpenViewInputArgs(source?: Record<string, unknown> | null) {
|
|
3162
|
+
return pickDefinedKeys(source, OPEN_VIEW_INHERITED_INPUT_ARG_KEYS);
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
function applyDefinedDefaults(target: Record<string, unknown>, defaults: Record<string, unknown>) {
|
|
3166
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
3167
|
+
if (typeof target[key] === 'undefined') {
|
|
3168
|
+
target[key] = value;
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3142
3173
|
export class FlowEngineContext extends BaseFlowEngineContext {
|
|
3143
3174
|
// public dataSourceManager: DataSourceManager;
|
|
3144
3175
|
constructor(public engine: FlowEngine) {
|
|
@@ -3687,7 +3718,14 @@ export class FlowModelContext extends BaseFlowModelContext {
|
|
|
3687
3718
|
},
|
|
3688
3719
|
});
|
|
3689
3720
|
this.defineMethod('openView', async function (uid: string, options) {
|
|
3690
|
-
const
|
|
3721
|
+
const inheritedInputArgs = {
|
|
3722
|
+
...(typeof this.model?.['getInputArgs'] === 'function'
|
|
3723
|
+
? pickDefinedOpenViewInputArgs(this.model['getInputArgs']())
|
|
3724
|
+
: {}),
|
|
3725
|
+
...pickDefinedOpenViewInputArgs(this.inputArgs),
|
|
3726
|
+
};
|
|
3727
|
+
const opts = { ...(options || {}) };
|
|
3728
|
+
applyDefinedDefaults(opts, inheritedInputArgs);
|
|
3691
3729
|
// NOTE: when custom context is passed, route navigation must be disabled to avoid losing it after refresh.
|
|
3692
3730
|
if (opts.defineProperties || opts.defineMethods) {
|
|
3693
3731
|
opts.navigation = false; // 强制不使用路由导航, 避免刷新页面时丢失上下文
|
|
@@ -3695,15 +3733,6 @@ export class FlowModelContext extends BaseFlowModelContext {
|
|
|
3695
3733
|
let model: FlowModel | null = null;
|
|
3696
3734
|
model = await this.engine.loadModel({ uid });
|
|
3697
3735
|
if (!model) {
|
|
3698
|
-
const pickDefined = (src: Record<string, any>, keys: string[]) => {
|
|
3699
|
-
const res: Record<string, any> = {};
|
|
3700
|
-
for (const k of keys) {
|
|
3701
|
-
if (typeof src?.[k] !== 'undefined') {
|
|
3702
|
-
res[k] = src[k];
|
|
3703
|
-
}
|
|
3704
|
-
}
|
|
3705
|
-
return res;
|
|
3706
|
-
};
|
|
3707
3736
|
model = this.engine.createModel({
|
|
3708
3737
|
uid, // 注意: 新建的 model 应该使用 ${parentModel.uid}-xxx 形式的 uid
|
|
3709
3738
|
use: 'PopupActionModel',
|
|
@@ -3714,7 +3743,7 @@ export class FlowModelContext extends BaseFlowModelContext {
|
|
|
3714
3743
|
popupSettings: {
|
|
3715
3744
|
openView: {
|
|
3716
3745
|
// 仅在创建时持久化一份默认配置;运行时以本次 opts 为准,避免多个 opener 互相覆盖。
|
|
3717
|
-
...
|
|
3746
|
+
...pickDefinedKeys(opts, ['dataSourceKey', 'collectionName', 'associationName', 'mode', 'size']),
|
|
3718
3747
|
},
|
|
3719
3748
|
},
|
|
3720
3749
|
},
|
|
@@ -3734,8 +3763,6 @@ export class FlowModelContext extends BaseFlowModelContext {
|
|
|
3734
3763
|
// 统一语义:为即将打开的外部视图定义一个 PendingView(占位视图)
|
|
3735
3764
|
const pendingType = (opts?.isMobileLayout ? 'embed' : opts?.mode || 'drawer') as any;
|
|
3736
3765
|
const pendingInputArgs = { ...opts, viewUid, navigation: opts.navigation };
|
|
3737
|
-
pendingInputArgs.filterByTk = pendingInputArgs.filterByTk || this.inputArgs?.filterByTk;
|
|
3738
|
-
pendingInputArgs.sourceId = pendingInputArgs.sourceId || this.inputArgs?.sourceId;
|
|
3739
3766
|
|
|
3740
3767
|
const pendingView = {
|
|
3741
3768
|
type: pendingType,
|
|
@@ -3754,17 +3781,10 @@ export class FlowModelContext extends BaseFlowModelContext {
|
|
|
3754
3781
|
} else if (on && typeof on === 'object' && typeof (on as any).eventName === 'string' && (on as any).eventName) {
|
|
3755
3782
|
openEventName = (on as any).eventName;
|
|
3756
3783
|
}
|
|
3757
|
-
await model.dispatchEvent(
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
// ...this.model?.['getInputArgs']?.(), // 避免部分关系字段信息丢失, 仿照 ClickableCollectionField 做法
|
|
3762
|
-
...opts,
|
|
3763
|
-
},
|
|
3764
|
-
{
|
|
3765
|
-
debounce: true,
|
|
3766
|
-
},
|
|
3767
|
-
);
|
|
3784
|
+
await model.dispatchEvent(openEventName, {
|
|
3785
|
+
// navigation: false, // TODO: 路由模式有bug,不支持多层同样viewId的弹窗,因此这里默认先用false
|
|
3786
|
+
...opts,
|
|
3787
|
+
});
|
|
3768
3788
|
});
|
|
3769
3789
|
this.defineMethod('getEvents', function (this: BaseFlowModelContext) {
|
|
3770
3790
|
return this.model.getEvents();
|