@nocobase/flow-engine 2.4.0-alpha.8 → 2.4.0-alpha.9
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.
|
@@ -360,7 +360,9 @@ function createPopupMeta(ctx, anchorView) {
|
|
|
360
360
|
const view = getPopupView(ctx, anchorView);
|
|
361
361
|
const inputArgs = view == null ? void 0 : view.inputArgs;
|
|
362
362
|
const srcId = inputArgs == null ? void 0 : inputArgs.sourceId;
|
|
363
|
-
|
|
363
|
+
const hasSourceId = srcId != null && srcId !== "";
|
|
364
|
+
const pendingSourceAssoc = !hasSourceId && typeof (inputArgs == null ? void 0 : inputArgs.sourceAssociationName) === "string" ? inputArgs.sourceAssociationName : void 0;
|
|
365
|
+
let assoc = (inputArgs == null ? void 0 : inputArgs.associationName) || pendingSourceAssoc;
|
|
364
366
|
let dsKey = (inputArgs == null ? void 0 : inputArgs.dataSourceKey) || "main";
|
|
365
367
|
if (!assoc || typeof assoc !== "string" || !assoc.includes(".")) {
|
|
366
368
|
const stack = getViewStack(view);
|
|
@@ -376,7 +378,7 @@ function createPopupMeta(ctx, anchorView) {
|
|
|
376
378
|
dsKey = (p == null ? void 0 : p.dataSourceKey) || dsKey;
|
|
377
379
|
}
|
|
378
380
|
}
|
|
379
|
-
if (
|
|
381
|
+
if ((hasSourceId || pendingSourceAssoc) && assoc && typeof assoc === "string") {
|
|
380
382
|
const parentCollectionName = String(assoc).includes(".") ? String(assoc).split(".")[0] : void 0;
|
|
381
383
|
if (parentCollectionName) {
|
|
382
384
|
const parentCollectionAccessor = /* @__PURE__ */ __name(() => {
|
|
@@ -388,11 +390,15 @@ function createPopupMeta(ctx, anchorView) {
|
|
|
388
390
|
return null;
|
|
389
391
|
}
|
|
390
392
|
}, "parentCollectionAccessor");
|
|
391
|
-
const srcMeta = await (0, import_variablesParams.buildRecordMeta)(
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
393
|
+
const srcMeta = await (0, import_variablesParams.buildRecordMeta)(
|
|
394
|
+
parentCollectionAccessor,
|
|
395
|
+
t("Current popup parent record"),
|
|
396
|
+
() => hasSourceId ? {
|
|
397
|
+
collection: parentCollectionName,
|
|
398
|
+
dataSourceKey: dsKey,
|
|
399
|
+
filterByTk: srcId
|
|
400
|
+
} : void 0
|
|
401
|
+
);
|
|
396
402
|
if (srcMeta) {
|
|
397
403
|
props.sourceRecord = srcMeta;
|
|
398
404
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/flow-engine",
|
|
3
|
-
"version": "2.4.0-alpha.
|
|
3
|
+
"version": "2.4.0-alpha.9",
|
|
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.4.0-alpha.
|
|
12
|
-
"@nocobase/shared": "2.4.0-alpha.
|
|
11
|
+
"@nocobase/sdk": "2.4.0-alpha.9",
|
|
12
|
+
"@nocobase/shared": "2.4.0-alpha.9",
|
|
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": "d383bdb224c62d1ba21c3dffd682165f3385a11b"
|
|
41
41
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { describe, it, expect, vi } from 'vitest';
|
|
11
|
-
import { FlowContext } from '../flowContext';
|
|
11
|
+
import { FlowContext, type PropertyMeta } from '../flowContext';
|
|
12
12
|
import { FlowEngine } from '../flowEngine';
|
|
13
13
|
import type { FlowView } from '../views/FlowView';
|
|
14
14
|
import { buildPopupRuntime, createPopupMeta, registerPopupVariable } from '../views/createViewMeta';
|
|
@@ -397,4 +397,86 @@ describe('createPopupMeta - popup variables', () => {
|
|
|
397
397
|
|
|
398
398
|
expect(ctx.getPropertyOptions('popup')?.resolveOnServer?.('sourceRecord.department.title')).toBe(true);
|
|
399
399
|
});
|
|
400
|
+
|
|
401
|
+
describe('popup sourceRecord meta for quick create popups', () => {
|
|
402
|
+
function makeCtxWithUsers() {
|
|
403
|
+
const engine = new FlowEngine();
|
|
404
|
+
const ds = engine.context.dataSourceManager.getDataSource('main');
|
|
405
|
+
ds.addCollection({
|
|
406
|
+
name: 'orgs',
|
|
407
|
+
filterTargetKey: 'id',
|
|
408
|
+
fields: [{ name: 'id', type: 'integer', interface: 'number' }],
|
|
409
|
+
});
|
|
410
|
+
ds.addCollection({
|
|
411
|
+
name: 'users',
|
|
412
|
+
filterTargetKey: 'id',
|
|
413
|
+
fields: [
|
|
414
|
+
{ name: 'id', type: 'integer', interface: 'number' },
|
|
415
|
+
{ name: 'nickname', type: 'string', interface: 'input' },
|
|
416
|
+
{ name: 'orgs', type: 'hasMany', target: 'orgs', interface: 'o2m' },
|
|
417
|
+
],
|
|
418
|
+
});
|
|
419
|
+
return engine.context;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function makeQuickCreatePopupView(inputArgs: Record<string, unknown>): FlowView {
|
|
423
|
+
return {
|
|
424
|
+
type: 'drawer',
|
|
425
|
+
inputArgs: {
|
|
426
|
+
openerUids: ['approval-form-uid'],
|
|
427
|
+
scene: 'create',
|
|
428
|
+
dataSourceKey: 'main',
|
|
429
|
+
collectionName: 'orgs',
|
|
430
|
+
...inputArgs,
|
|
431
|
+
},
|
|
432
|
+
Header: null,
|
|
433
|
+
Footer: null,
|
|
434
|
+
close: () => void 0,
|
|
435
|
+
update: () => void 0,
|
|
436
|
+
} as unknown as FlowView;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
async function getPopupProps(ctx: FlowContext, view: FlowView) {
|
|
440
|
+
const meta = await createPopupMeta(ctx, view)();
|
|
441
|
+
const props = typeof meta?.properties === 'function' ? await meta.properties() : meta?.properties;
|
|
442
|
+
return { meta, props: props || {} };
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
it('exposes the parent record meta from sourceAssociationName before the parent record has a primary key', async () => {
|
|
446
|
+
const ctx = makeCtxWithUsers();
|
|
447
|
+
const view = makeQuickCreatePopupView({ sourceAssociationName: 'users.orgs' });
|
|
448
|
+
|
|
449
|
+
const { meta, props } = await getPopupProps(ctx, view);
|
|
450
|
+
const sourceRecordMeta = props.sourceRecord as PropertyMeta;
|
|
451
|
+
expect(sourceRecordMeta?.title).toBe('Current popup parent record');
|
|
452
|
+
const fields =
|
|
453
|
+
typeof sourceRecordMeta.properties === 'function'
|
|
454
|
+
? await sourceRecordMeta.properties()
|
|
455
|
+
: sourceRecordMeta.properties;
|
|
456
|
+
expect(fields).toHaveProperty('nickname');
|
|
457
|
+
|
|
458
|
+
// 父记录尚无主键时仅用于配置变量,不应生成服务端取值参数
|
|
459
|
+
const vars = (await meta?.buildVariablesParams?.(ctx)) as { sourceRecord?: unknown } | undefined;
|
|
460
|
+
expect(vars?.sourceRecord).toBeUndefined();
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
it('does not expose the parent record meta without sourceId or sourceAssociationName', async () => {
|
|
464
|
+
const ctx = makeCtxWithUsers();
|
|
465
|
+
const view = makeQuickCreatePopupView({});
|
|
466
|
+
|
|
467
|
+
const { props } = await getPopupProps(ctx, view);
|
|
468
|
+
expect(props.sourceRecord).toBeUndefined();
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
it('keeps resolving the parent record by sourceId once the parent record is persisted', async () => {
|
|
472
|
+
const ctx = makeCtxWithUsers();
|
|
473
|
+
const view = makeQuickCreatePopupView({ associationName: 'users.orgs', sourceId: 7 });
|
|
474
|
+
|
|
475
|
+
const { meta, props } = await getPopupProps(ctx, view);
|
|
476
|
+
expect((props.sourceRecord as PropertyMeta)?.title).toBe('Current popup parent record');
|
|
477
|
+
|
|
478
|
+
const vars = (await meta?.buildVariablesParams?.(ctx)) as { sourceRecord?: unknown } | undefined;
|
|
479
|
+
expect(vars?.sourceRecord).toEqual({ collection: 'users', dataSourceKey: 'main', filterByTk: 7 });
|
|
480
|
+
});
|
|
481
|
+
});
|
|
400
482
|
});
|
|
@@ -390,7 +390,13 @@ export function createPopupMeta(ctx: FlowContext, anchorView?: FlowView): Proper
|
|
|
390
390
|
const view = getPopupView(ctx, anchorView);
|
|
391
391
|
const inputArgs = view?.inputArgs;
|
|
392
392
|
const srcId = inputArgs?.sourceId;
|
|
393
|
-
|
|
393
|
+
const hasSourceId = srcId != null && srcId !== '';
|
|
394
|
+
// 上级记录暂无主键时(如审批配置态表单里的快速创建弹窗),只会传 sourceAssociationName:仍展示变量结构,取值依赖运行时的 sourceId
|
|
395
|
+
const pendingSourceAssoc =
|
|
396
|
+
!hasSourceId && typeof inputArgs?.sourceAssociationName === 'string'
|
|
397
|
+
? inputArgs.sourceAssociationName
|
|
398
|
+
: undefined;
|
|
399
|
+
let assoc: string | undefined = inputArgs?.associationName || pendingSourceAssoc;
|
|
394
400
|
let dsKey: string = inputArgs?.dataSourceKey || 'main';
|
|
395
401
|
|
|
396
402
|
// 兜底:若 associationName 缺失或不含“.”,尝试从当前视图模型的 openView 参数推断
|
|
@@ -409,7 +415,7 @@ export function createPopupMeta(ctx: FlowContext, anchorView?: FlowView): Proper
|
|
|
409
415
|
}
|
|
410
416
|
}
|
|
411
417
|
|
|
412
|
-
if (
|
|
418
|
+
if ((hasSourceId || pendingSourceAssoc) && assoc && typeof assoc === 'string') {
|
|
413
419
|
const parentCollectionName = String(assoc).includes('.') ? String(assoc).split('.')[0] : undefined;
|
|
414
420
|
if (parentCollectionName) {
|
|
415
421
|
const parentCollectionAccessor = () => {
|
|
@@ -420,11 +426,15 @@ export function createPopupMeta(ctx: FlowContext, anchorView?: FlowView): Proper
|
|
|
420
426
|
return null;
|
|
421
427
|
}
|
|
422
428
|
};
|
|
423
|
-
const srcMeta = await buildRecordMeta(parentCollectionAccessor, t('Current popup parent record'), () =>
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
429
|
+
const srcMeta = await buildRecordMeta(parentCollectionAccessor, t('Current popup parent record'), () =>
|
|
430
|
+
hasSourceId
|
|
431
|
+
? {
|
|
432
|
+
collection: parentCollectionName,
|
|
433
|
+
dataSourceKey: dsKey,
|
|
434
|
+
filterByTk: srcId,
|
|
435
|
+
}
|
|
436
|
+
: undefined,
|
|
437
|
+
);
|
|
428
438
|
if (srcMeta) {
|
|
429
439
|
props.sourceRecord = srcMeta;
|
|
430
440
|
}
|