@nocobase/flow-engine 2.0.0-alpha.51 → 2.0.0-alpha.52

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.
@@ -130,9 +130,21 @@ const transformSubModelItems = /* @__PURE__ */ __name(async (items, model, subMo
130
130
  const toggleItems = [];
131
131
  for (let i = 0; i < items.length; i++) {
132
132
  const item = items[i];
133
- if (item.toggleable && item.useModel) {
133
+ let resolvedUseModel = item.useModel;
134
+ if (!resolvedUseModel && item.toggleable) {
135
+ try {
136
+ const createOpts = await getCreateModelOptions(item, model.context);
137
+ resolvedUseModel = createOpts == null ? void 0 : createOpts.use;
138
+ if (resolvedUseModel) {
139
+ item.useModel = resolvedUseModel;
140
+ }
141
+ } catch (error) {
142
+ console.error("[NocoBase]: Failed to resolve useModel for toggleable item:", error);
143
+ }
144
+ }
145
+ if (item.toggleable && resolvedUseModel) {
134
146
  item.toggleDetector = (ctx) => {
135
- const C = ctx.engine.getModelClass(item.useModel);
147
+ const C = ctx.engine.getModelClass(resolvedUseModel);
136
148
  const r = ctx.model.findSubModel(subModelKey, (m) => {
137
149
  if (item.toggleable === true) {
138
150
  return m.constructor === C;
@@ -143,7 +155,7 @@ const transformSubModelItems = /* @__PURE__ */ __name(async (items, model, subMo
143
155
  return !!r;
144
156
  };
145
157
  item.customRemove = async (ctx, item2) => {
146
- const C = ctx.engine.getModelClass(item2.useModel);
158
+ const C = ctx.engine.getModelClass(resolvedUseModel);
147
159
  const r = ctx.model.findSubModel(subModelKey, (m) => {
148
160
  if (item2.toggleable === true) {
149
161
  return m.constructor === C;
@@ -671,7 +671,19 @@ const _CollectionField = class _CollectionField {
671
671
  }
672
672
  get enum() {
673
673
  var _a;
674
- return ((_a = this.options.uiSchema) == null ? void 0 : _a.enum) || [];
674
+ const options = ((_a = this.options.uiSchema) == null ? void 0 : _a.enum) || [];
675
+ if (this.type === "integer") {
676
+ return options.map((v) => {
677
+ if (typeof v !== "object") {
678
+ return v;
679
+ }
680
+ return {
681
+ ...v,
682
+ value: Number(v.value)
683
+ };
684
+ });
685
+ }
686
+ return options;
675
687
  }
676
688
  get defaultValue() {
677
689
  return this.options.defaultValue == null ? void 0 : this.options.defaultValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/flow-engine",
3
- "version": "2.0.0-alpha.51",
3
+ "version": "2.0.0-alpha.52",
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.0.0-alpha.51",
12
- "@nocobase/shared": "2.0.0-alpha.51",
11
+ "@nocobase/sdk": "2.0.0-alpha.52",
12
+ "@nocobase/shared": "2.0.0-alpha.52",
13
13
  "ahooks": "^3.7.2",
14
14
  "dayjs": "^1.11.9",
15
15
  "dompurify": "^3.0.2",
@@ -36,5 +36,5 @@
36
36
  ],
37
37
  "author": "NocoBase Team",
38
38
  "license": "AGPL-3.0",
39
- "gitHead": "a1e34dd97f370d54f3d80a6b83ab7ddb9c72dc18"
39
+ "gitHead": "b32992d8baeb4ca6616d839ca2f9c023d49476a9"
40
40
  }
@@ -208,9 +208,25 @@ const transformSubModelItems = async (
208
208
  const toggleItems: Array<{ item: SubModelItem; index: number }> = [];
209
209
  for (let i = 0; i < items.length; i++) {
210
210
  const item = items[i];
211
- if (item.toggleable && item.useModel) {
211
+
212
+ // 自动从 createModelOptions 中推断 useModel,避免遗漏导致 toggleable 失效
213
+ let resolvedUseModel = item.useModel;
214
+ if (!resolvedUseModel && item.toggleable) {
215
+ try {
216
+ const createOpts = await getCreateModelOptions(item, model.context);
217
+ resolvedUseModel = createOpts?.use;
218
+ if (resolvedUseModel) {
219
+ item.useModel = resolvedUseModel;
220
+ }
221
+ } catch (error) {
222
+ // ignore and fall back to existing useModel
223
+ console.error('[NocoBase]: Failed to resolve useModel for toggleable item:', error);
224
+ }
225
+ }
226
+
227
+ if (item.toggleable && resolvedUseModel) {
212
228
  item.toggleDetector = (ctx) => {
213
- const C = ctx.engine.getModelClass(item.useModel); // 确保 use 是有效的模型类
229
+ const C = ctx.engine.getModelClass(resolvedUseModel); // 确保 use 是有效的模型类
214
230
  const r = ctx.model.findSubModel(subModelKey, (m) => {
215
231
  if (item.toggleable === true) {
216
232
  return m.constructor === C;
@@ -221,7 +237,7 @@ const transformSubModelItems = async (
221
237
  return !!r;
222
238
  };
223
239
  item.customRemove = async (ctx, item) => {
224
- const C = ctx.engine.getModelClass(item.useModel); // 确保 use 是有效的模型类
240
+ const C = ctx.engine.getModelClass(resolvedUseModel); // 确保 use 是有效的模型类
225
241
  const r = ctx.model.findSubModel(subModelKey, (m) => {
226
242
  if (item.toggleable === true) {
227
243
  return m.constructor === C;
@@ -233,6 +233,32 @@ describe('transformItems - toggleable items', () => {
233
233
  expect(((parent.subModels as any).items || []).length).toBe(0);
234
234
  });
235
235
 
236
+ it('infers useModel from createModelOptions when toggleable is enabled', async () => {
237
+ const engine = setupEngine();
238
+ const parent = engine.createModel<ToggleParent>({ use: 'ToggleParent', uid: 'toggle-parent-infer' });
239
+ const child = engine.createModel<ToggleChild>({ use: 'ToggleChild', uid: 'toggle-child-infer' });
240
+ parent.addSubModel('items', child);
241
+
242
+ const definition: SubModelItem[] = [
243
+ {
244
+ key: 'toggle-child',
245
+ label: 'Toggle Child',
246
+ toggleable: true,
247
+ // intentionally omit useModel to rely on createModelOptions.use
248
+ createModelOptions: { use: 'ToggleChild' },
249
+ },
250
+ ];
251
+
252
+ const factory = transformItems(definition, parent, 'items', 'array');
253
+ const resolved = await (typeof factory === 'function' ? factory() : Promise.resolve(factory));
254
+ const toggleItem = resolved[0];
255
+
256
+ expect(definition[0].useModel).toBe('ToggleChild');
257
+ expect(toggleItem.isToggled).toBe(true);
258
+ const { getByRole } = render(<>{toggleItem.label}</>);
259
+ expect(getByRole('switch')).toHaveAttribute('aria-checked', 'true');
260
+ });
261
+
236
262
  it('keeps toggleable item off when sub model missing', async () => {
237
263
  const engine = setupEngine();
238
264
  const parent = engine.createModel<ToggleParent>({ use: 'ToggleParent', uid: 'toggle-parent-off' });
@@ -8,8 +8,8 @@
8
8
  */
9
9
 
10
10
  import { observable } from '@formily/reactive';
11
- import _ from 'lodash';
12
11
  import { CascaderProps } from 'antd';
12
+ import _ from 'lodash';
13
13
  import { FlowEngine } from '../flowEngine';
14
14
  import { jioToJoiSchema } from './jioToJoiSchema';
15
15
  import { sortCollectionsByInherits } from './sortCollectionsByInherits';
@@ -803,7 +803,19 @@ export class CollectionField {
803
803
  }
804
804
 
805
805
  get enum(): any[] {
806
- return this.options.uiSchema?.enum || [];
806
+ const options = this.options.uiSchema?.enum || [];
807
+ if (this.type === 'integer') {
808
+ return options.map((v) => {
809
+ if (typeof v !== 'object') {
810
+ return v;
811
+ }
812
+ return {
813
+ ...v,
814
+ value: Number(v.value),
815
+ };
816
+ });
817
+ }
818
+ return options;
807
819
  }
808
820
 
809
821
  get defaultValue() {