@nocobase/plugin-flow-engine 2.1.0-beta.21 → 2.1.0-beta.23

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.
@@ -8,16 +8,16 @@
8
8
  */
9
9
 
10
10
  module.exports = {
11
- "@nocobase/client": "2.1.0-beta.21",
11
+ "@nocobase/client": "2.1.0-beta.23",
12
12
  "lodash": "4.18.1",
13
- "@nocobase/database": "2.1.0-beta.21",
14
- "@nocobase/data-source-manager": "2.1.0-beta.21",
15
- "@nocobase/resourcer": "2.1.0-beta.21",
16
- "@nocobase/utils": "2.1.0-beta.21",
17
- "@nocobase/cache": "2.1.0-beta.21",
18
- "@nocobase/plugin-localization": "2.1.0-beta.21",
19
- "@nocobase/server": "2.1.0-beta.21",
20
- "@nocobase/actions": "2.1.0-beta.21",
13
+ "@nocobase/database": "2.1.0-beta.23",
14
+ "@nocobase/data-source-manager": "2.1.0-beta.23",
15
+ "@nocobase/resourcer": "2.1.0-beta.23",
16
+ "@nocobase/utils": "2.1.0-beta.23",
17
+ "@nocobase/cache": "2.1.0-beta.23",
18
+ "@nocobase/plugin-localization": "2.1.0-beta.23",
19
+ "@nocobase/server": "2.1.0-beta.23",
20
+ "@nocobase/actions": "2.1.0-beta.23",
21
21
  "@formily/json-schema": "2.3.7",
22
- "@nocobase/ai": "2.1.0-beta.21"
22
+ "@nocobase/ai": "2.1.0-beta.23"
23
23
  };
@@ -1 +1 @@
1
- {"name":"ses","version":"1.14.0","description":"Hardened JavaScript for Fearless Cooperation","keywords":["lockdown","harden","Compartment","assert","security","confinement","isolation","object capabilities","ocaps","secure execution","third-party code","prototype pollution","supply-chain attack","plugin"],"author":"Agoric","license":"Apache-2.0","homepage":"https://github.com/Agoric/SES-shim/tree/master/packages/ses#readme","repository":{"type":"git","url":"git+https://github.com/endojs/endo.git","directory":"packages/ses"},"bugs":{"url":"https://github.com/endojs/endo/issues"},"type":"module","main":"./dist/ses.cjs","module":"./index.js","unpkg":"./dist/ses.umd.js","types":"./types.d.ts","exports":{".":{"import":{"types":"./types.d.ts","xs":"./src-xs/index.js","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./lockdown":{"import":{"types":"./types.d.ts","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./hermes":{"require":{"types":"./dist/types.d.cts","default":"./dist/ses-hermes.cjs"}},"./tools.js":"./tools.js","./assert-shim.js":"./assert-shim.js","./lockdown-shim.js":{"xs":"./src-xs/lockdown-shim.js","default":"./lockdown-shim.js"},"./compartment-shim.js":{"xs":"./src-xs/compartment-shim.js","default":"./compartment-shim.js"},"./console-shim.js":"./console-shim.js","./package.json":"./package.json"},"scripts":{"build:vanilla":"node scripts/bundle.js","build:hermes":"node scripts/bundle.js hermes","build":"yarn build:vanilla && yarn build:hermes","clean":"rm -rf dist","cover":"c8 ava","demo":"python3 -m http.server","lint":"yarn lint:types && yarn lint:eslint","lint-fix":"eslint --fix .","lint:eslint":"eslint .","lint:types":"tsc","prepare":"npm run clean && npm run build","qt":"ava","test":"tsd && ava","test:hermes":"./scripts/hermes-test.sh","test:xs":"xst dist/ses.umd.js test/_lockdown-safe.js && node scripts/generate-test-xs.js && xst tmp/test-xs.js && rm -rf tmp","postpack":"git clean -fX \"*.d.ts*\" \"*.d.cts*\" \"*.d.mts*\" \"*.tsbuildinfo\""},"dependencies":{"@endo/cache-map":"^1.1.0","@endo/env-options":"^1.1.11","@endo/immutable-arraybuffer":"^1.1.2"},"devDependencies":{"@babel/generator":"^7.26.3","@babel/parser":"~7.26.2","@babel/traverse":"~7.25.9","@babel/types":"~7.26.0","@endo/compartment-mapper":"^1.6.3","@endo/module-source":"^1.3.3","@endo/test262-runner":"^0.1.48","@types/babel__traverse":"^7.20.5","ava":"^6.1.3","babel-eslint":"^10.1.0","c8":"^7.14.0","core-js":"^3.31.0","eslint":"^8.57.1","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","hermes-engine-cli":"^0.12.0","prettier":"^3.5.3","terser":"^5.16.6","tsd":"^0.31.2","typescript":"~5.8.3"},"files":["./*.d.ts","./*.js","./*.map","LICENSE*","SECURITY*","dist","lib","src","tools"],"publishConfig":{"access":"public"},"eslintConfig":{"extends":["plugin:@endo/ses"]},"ava":{"files":["test/**/*.test.*"],"timeout":"2m"},"typeCoverage":{"atLeast":81.17},"gitHead":"9815aea9541f241389d2135c6097a7442bdffa17","_lastModified":"2026-04-27T17:01:55.631Z"}
1
+ {"name":"ses","version":"1.14.0","description":"Hardened JavaScript for Fearless Cooperation","keywords":["lockdown","harden","Compartment","assert","security","confinement","isolation","object capabilities","ocaps","secure execution","third-party code","prototype pollution","supply-chain attack","plugin"],"author":"Agoric","license":"Apache-2.0","homepage":"https://github.com/Agoric/SES-shim/tree/master/packages/ses#readme","repository":{"type":"git","url":"git+https://github.com/endojs/endo.git","directory":"packages/ses"},"bugs":{"url":"https://github.com/endojs/endo/issues"},"type":"module","main":"./dist/ses.cjs","module":"./index.js","unpkg":"./dist/ses.umd.js","types":"./types.d.ts","exports":{".":{"import":{"types":"./types.d.ts","xs":"./src-xs/index.js","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./lockdown":{"import":{"types":"./types.d.ts","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./hermes":{"require":{"types":"./dist/types.d.cts","default":"./dist/ses-hermes.cjs"}},"./tools.js":"./tools.js","./assert-shim.js":"./assert-shim.js","./lockdown-shim.js":{"xs":"./src-xs/lockdown-shim.js","default":"./lockdown-shim.js"},"./compartment-shim.js":{"xs":"./src-xs/compartment-shim.js","default":"./compartment-shim.js"},"./console-shim.js":"./console-shim.js","./package.json":"./package.json"},"scripts":{"build:vanilla":"node scripts/bundle.js","build:hermes":"node scripts/bundle.js hermes","build":"yarn build:vanilla && yarn build:hermes","clean":"rm -rf dist","cover":"c8 ava","demo":"python3 -m http.server","lint":"yarn lint:types && yarn lint:eslint","lint-fix":"eslint --fix .","lint:eslint":"eslint .","lint:types":"tsc","prepare":"npm run clean && npm run build","qt":"ava","test":"tsd && ava","test:hermes":"./scripts/hermes-test.sh","test:xs":"xst dist/ses.umd.js test/_lockdown-safe.js && node scripts/generate-test-xs.js && xst tmp/test-xs.js && rm -rf tmp","postpack":"git clean -fX \"*.d.ts*\" \"*.d.cts*\" \"*.d.mts*\" \"*.tsbuildinfo\""},"dependencies":{"@endo/cache-map":"^1.1.0","@endo/env-options":"^1.1.11","@endo/immutable-arraybuffer":"^1.1.2"},"devDependencies":{"@babel/generator":"^7.26.3","@babel/parser":"~7.26.2","@babel/traverse":"~7.25.9","@babel/types":"~7.26.0","@endo/compartment-mapper":"^1.6.3","@endo/module-source":"^1.3.3","@endo/test262-runner":"^0.1.48","@types/babel__traverse":"^7.20.5","ava":"^6.1.3","babel-eslint":"^10.1.0","c8":"^7.14.0","core-js":"^3.31.0","eslint":"^8.57.1","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","hermes-engine-cli":"^0.12.0","prettier":"^3.5.3","terser":"^5.16.6","tsd":"^0.31.2","typescript":"~5.8.3"},"files":["./*.d.ts","./*.js","./*.map","LICENSE*","SECURITY*","dist","lib","src","tools"],"publishConfig":{"access":"public"},"eslintConfig":{"extends":["plugin:@endo/ses"]},"ava":{"files":["test/**/*.test.*"],"timeout":"2m"},"typeCoverage":{"atLeast":81.17},"gitHead":"9815aea9541f241389d2135c6097a7442bdffa17","_lastModified":"2026-04-28T15:59:20.625Z"}
@@ -1 +1 @@
1
- {"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-04-27T17:01:56.550Z"}
1
+ {"name":"zod","version":"4.3.5","type":"module","license":"MIT","author":"Colin McDonnell <zod@colinhacks.com>","description":"TypeScript-first schema declaration and validation library with static type inference","homepage":"https://zod.dev","llms":"https://zod.dev/llms.txt","llmsFull":"https://zod.dev/llms-full.txt","mcpServer":"https://mcp.inkeep.com/zod/mcp","funding":"https://github.com/sponsors/colinhacks","sideEffects":false,"files":["src","**/*.js","**/*.mjs","**/*.cjs","**/*.d.ts","**/*.d.mts","**/*.d.cts","**/package.json"],"keywords":["typescript","schema","validation","type","inference"],"main":"./index.cjs","types":"./index.d.cts","module":"./index.js","zshy":{"exports":{"./package.json":"./package.json",".":"./src/index.ts","./mini":"./src/mini/index.ts","./locales":"./src/locales/index.ts","./v3":"./src/v3/index.ts","./v4":"./src/v4/index.ts","./v4-mini":"./src/v4-mini/index.ts","./v4/mini":"./src/v4/mini/index.ts","./v4/core":"./src/v4/core/index.ts","./v4/locales":"./src/v4/locales/index.ts","./v4/locales/*":"./src/v4/locales/*"},"conditions":{"@zod/source":"src"}},"exports":{"./package.json":"./package.json",".":{"@zod/source":"./src/index.ts","types":"./index.d.cts","import":"./index.js","require":"./index.cjs"},"./mini":{"@zod/source":"./src/mini/index.ts","types":"./mini/index.d.cts","import":"./mini/index.js","require":"./mini/index.cjs"},"./locales":{"@zod/source":"./src/locales/index.ts","types":"./locales/index.d.cts","import":"./locales/index.js","require":"./locales/index.cjs"},"./v3":{"@zod/source":"./src/v3/index.ts","types":"./v3/index.d.cts","import":"./v3/index.js","require":"./v3/index.cjs"},"./v4":{"@zod/source":"./src/v4/index.ts","types":"./v4/index.d.cts","import":"./v4/index.js","require":"./v4/index.cjs"},"./v4-mini":{"@zod/source":"./src/v4-mini/index.ts","types":"./v4-mini/index.d.cts","import":"./v4-mini/index.js","require":"./v4-mini/index.cjs"},"./v4/mini":{"@zod/source":"./src/v4/mini/index.ts","types":"./v4/mini/index.d.cts","import":"./v4/mini/index.js","require":"./v4/mini/index.cjs"},"./v4/core":{"@zod/source":"./src/v4/core/index.ts","types":"./v4/core/index.d.cts","import":"./v4/core/index.js","require":"./v4/core/index.cjs"},"./v4/locales":{"@zod/source":"./src/v4/locales/index.ts","types":"./v4/locales/index.d.cts","import":"./v4/locales/index.js","require":"./v4/locales/index.cjs"},"./v4/locales/*":{"@zod/source":"./src/v4/locales/*","types":"./v4/locales/*","import":"./v4/locales/*","require":"./v4/locales/*"}},"repository":{"type":"git","url":"git+https://github.com/colinhacks/zod.git"},"bugs":{"url":"https://github.com/colinhacks/zod/issues"},"support":{"backing":{"npm-funding":true}},"scripts":{"clean":"git clean -xdf . -e node_modules","build":"zshy --project tsconfig.build.json","postbuild":"tsx ../../scripts/write-stub-package-jsons.ts && pnpm biome check --write .","test:watch":"pnpm vitest","test":"pnpm vitest run","prepublishOnly":"tsx ../../scripts/check-versions.ts"},"_lastModified":"2026-04-28T15:59:21.674Z"}
@@ -800,6 +800,60 @@ function resolveTargetBlockKey(value, localBlockKeys, context) {
800
800
  }
801
801
  (0, import_errors.throwBadRequest)(`${context} must be a string block key`);
802
802
  }
803
+ function collectTreeConnectTargetKeys(settings, context) {
804
+ if (!import_lodash.default.isPlainObject(settings == null ? void 0 : settings.connectFields)) {
805
+ return [];
806
+ }
807
+ if (import_lodash.default.isUndefined(settings.connectFields.targets)) {
808
+ return [];
809
+ }
810
+ if (!Array.isArray(settings.connectFields.targets)) {
811
+ (0, import_errors.throwBadRequest)(`${context}.settings.connectFields.targets must be an array`);
812
+ }
813
+ const seenTargets = /* @__PURE__ */ new Set();
814
+ return settings.connectFields.targets.map((target, targetIndex) => {
815
+ if (!import_lodash.default.isPlainObject(target)) {
816
+ (0, import_errors.throwBadRequest)(`${context}.settings.connectFields.targets[${targetIndex}] must be an object`);
817
+ }
818
+ if (import_lodash.default.isUndefined(target.target) || target.target === null || target.target === "") {
819
+ return "";
820
+ }
821
+ if (typeof target.target !== "string") {
822
+ (0, import_errors.throwBadRequest)(`${context}.settings.connectFields.targets[${targetIndex}].target must be a string block key`);
823
+ }
824
+ const normalizedTarget = (0, import_service_utils.normalizeFlowSurfaceComposeKey)(
825
+ target.target,
826
+ `${context}.settings.connectFields.targets[${targetIndex}].target`
827
+ );
828
+ if (seenTargets.has(normalizedTarget)) {
829
+ (0, import_errors.throwBadRequest)(
830
+ `${context}.settings.connectFields.targets[${targetIndex}].target duplicate target '${normalizedTarget}' in tree connectFields`
831
+ );
832
+ }
833
+ seenTargets.add(normalizedTarget);
834
+ return normalizedTarget;
835
+ }).filter(Boolean);
836
+ }
837
+ function compileTreeConnectSettingsTargets(settings, localBlockKeys, context) {
838
+ if (!import_lodash.default.isPlainObject(settings == null ? void 0 : settings.connectFields) || !Array.isArray(settings.connectFields.targets)) {
839
+ return settings;
840
+ }
841
+ const nextSettings = import_lodash.default.cloneDeep(settings);
842
+ nextSettings.connectFields.targets = nextSettings.connectFields.targets.map((target, targetIndex) => {
843
+ if (!import_lodash.default.isPlainObject(target) || import_lodash.default.isUndefined(target.target) || target.target === null || target.target === "") {
844
+ return target;
845
+ }
846
+ return {
847
+ ...target,
848
+ target: resolveTargetBlockKey(
849
+ target.target,
850
+ localBlockKeys,
851
+ `${context}.settings.connectFields.targets[${targetIndex}].target`
852
+ )
853
+ };
854
+ });
855
+ return nextSettings;
856
+ }
803
857
  function compileField(input, index, scopePrefix, assets, localBlockKeys, context, popupDefaultsMetadata, defaults) {
804
858
  if (typeof input === "string") {
805
859
  const fieldPath2 = (0, import_private_utils.assertNonEmptyString)(input, `${context}[${index}]`);
@@ -919,6 +973,9 @@ function compileBlocks(input, scopePrefix, assets, context, defaults, requiredEx
919
973
  assertApplyBlueprintKanbanMainContent(block, `${context}[${index}]`);
920
974
  assertApplyBlueprintTreeMainContent(block, `${context}[${index}]`);
921
975
  const fields = resolveBlockFieldInputs(block, `${context}[${index}]`);
976
+ collectTreeConnectTargetKeys(block.settings, `${context}[${index}]`).forEach((targetKey) => {
977
+ referencedBlockKeys.add(targetKey);
978
+ });
922
979
  fields.forEach((field, fieldIndex) => {
923
980
  if (typeof (field == null ? void 0 : field.target) !== "string" || !field.target.trim()) {
924
981
  return;
@@ -1032,7 +1089,7 @@ function compileBlocks(input, scopePrefix, assets, context, defaults, requiredEx
1032
1089
  type: blockType,
1033
1090
  resource: buildBlockResource(block, blockContext),
1034
1091
  template,
1035
- settings: Object.keys(settings).length ? settings : void 0,
1092
+ settings: Object.keys(settings).length ? compileTreeConnectSettingsTargets(settings, blockKeysByLocalKey, blockContext) : void 0,
1036
1093
  fields: blockType === "calendar" || blockType === "tree" ? void 0 : fields,
1037
1094
  fieldsLayout: blockType === "calendar" || blockType === "kanban" || blockType === "tree" ? void 0 : fieldsLayout,
1038
1095
  actions: blockType === "tree" ? void 0 : actionsWithDefaultFilter,
@@ -1030,6 +1030,24 @@ function buildBlockDefaults(use) {
1030
1030
  defaultView: "month",
1031
1031
  enableQuickCreateEvent: true,
1032
1032
  weekStart: 1
1033
+ },
1034
+ stepParams: {
1035
+ cardSettings: {
1036
+ blockHeight: {
1037
+ heightMode: "fullHeight"
1038
+ }
1039
+ }
1040
+ }
1041
+ };
1042
+ }
1043
+ if (use === "KanbanBlockModel") {
1044
+ return {
1045
+ stepParams: {
1046
+ cardSettings: {
1047
+ blockHeight: {
1048
+ heightMode: "fullHeight"
1049
+ }
1050
+ }
1033
1051
  }
1034
1052
  };
1035
1053
  }
@@ -72,6 +72,10 @@ const OPEN_VIEW_SCENE_SCHEMA = {
72
72
  const OBJECT_SCHEMA = { type: "object" };
73
73
  const NUMBER_SCHEMA = { type: "number" };
74
74
  const ARRAY_SCHEMA = { type: "array" };
75
+ const BLOCK_HEIGHT_MODE_SCHEMA = {
76
+ type: "string",
77
+ enum: ["defaultHeight", "specifyValue", "fullHeight"]
78
+ };
75
79
  const NULLABLE_NUMBER_OR_STRING_SCHEMA = {
76
80
  oneOf: [NUMBER_SCHEMA, NULLABLE_STRING_SCHEMA]
77
81
  };
@@ -295,13 +299,21 @@ const FILTER_FORM_BLOCK_SETTINGS_GROUP = {
295
299
  }
296
300
  };
297
301
  const BLOCK_CARD_SETTINGS_GROUP = {
298
- allowedPaths: ["titleDescription.title", "titleDescription.description", "linkageRules"],
302
+ allowedPaths: [
303
+ "titleDescription.title",
304
+ "titleDescription.description",
305
+ "blockHeight.heightMode",
306
+ "blockHeight.height",
307
+ "linkageRules"
308
+ ],
299
309
  clearable: true,
300
310
  mergeStrategy: "deep",
301
- eventBindingSteps: ["titleDescription", "linkageRules"],
311
+ eventBindingSteps: ["titleDescription", "blockHeight", "linkageRules"],
302
312
  pathSchemas: {
303
313
  "titleDescription.title": STRING_SCHEMA,
304
314
  "titleDescription.description": STRING_SCHEMA,
315
+ "blockHeight.heightMode": BLOCK_HEIGHT_MODE_SCHEMA,
316
+ "blockHeight.height": NUMBER_SCHEMA,
305
317
  linkageRules: ARRAY_SCHEMA
306
318
  }
307
319
  };
@@ -833,8 +845,6 @@ TAB_NODE_CONTRACT.domains.stepParams = groupedDomain({
833
845
  });
834
846
  const TABLE_BLOCK_CONTRACT = createContract({
835
847
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
836
- props: ["height", "heightMode"],
837
- decoratorProps: ["height", "heightMode"],
838
848
  stepParams: ["resourceSettings", "tableSettings", "cardSettings"],
839
849
  flowRegistry: true,
840
850
  eventCapabilities: {
@@ -942,7 +952,6 @@ const CALENDAR_BLOCK_CONTRACT = createContract({
942
952
  "quickCreatePopupSettings",
943
953
  "eventPopupSettings"
944
954
  ],
945
- decoratorProps: ["height", "heightMode"],
946
955
  stepParams: ["resourceSettings", "calendarSettings", "cardSettings"],
947
956
  flowRegistry: true,
948
957
  eventCapabilities: {
@@ -958,7 +967,6 @@ CALENDAR_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
958
967
  const TREE_BLOCK_CONTRACT = createContract({
959
968
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
960
969
  props: ["searchable", "defaultExpandAll", "includeDescendants", "fieldNames", "pageSize"],
961
- decoratorProps: ["height", "heightMode"],
962
970
  stepParams: ["resourceSettings", "treeSettings", "cardSettings"],
963
971
  flowRegistry: true,
964
972
  eventCapabilities: {
@@ -997,7 +1005,6 @@ const KANBAN_BLOCK_CONTRACT = createContract({
997
1005
  "pageSize",
998
1006
  "columnWidth"
999
1007
  ],
1000
- decoratorProps: ["height", "heightMode"],
1001
1008
  stepParams: ["resourceSettings", "kanbanSettings", "cardSettings"],
1002
1009
  flowRegistry: true,
1003
1010
  eventCapabilities: {
@@ -1013,7 +1020,6 @@ KANBAN_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
1013
1020
  const LIST_BLOCK_CONTRACT = createContract({
1014
1021
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
1015
1022
  props: [],
1016
- decoratorProps: ["height", "heightMode"],
1017
1023
  stepParams: ["resourceSettings", "listSettings", "cardSettings"],
1018
1024
  flowRegistry: true,
1019
1025
  eventCapabilities: {
@@ -1053,7 +1059,6 @@ LIST_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
1053
1059
  const GRID_CARD_BLOCK_CONTRACT = createContract({
1054
1060
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
1055
1061
  props: [],
1056
- decoratorProps: ["height", "heightMode"],
1057
1062
  stepParams: ["resourceSettings", "GridCardSettings", "cardSettings"],
1058
1063
  flowRegistry: true,
1059
1064
  eventCapabilities: {
@@ -1217,22 +1222,12 @@ IFRAME_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
1217
1222
  }
1218
1223
  });
1219
1224
  const CHART_CARD_SETTINGS_GROUP = {
1220
- allowedPaths: [
1221
- "titleDescription.title",
1222
- "titleDescription.description",
1223
- "blockHeight.heightMode",
1224
- "blockHeight.height",
1225
- "linkageRules"
1226
- ],
1225
+ allowedPaths: BLOCK_CARD_SETTINGS_GROUP.allowedPaths,
1227
1226
  clearable: true,
1228
1227
  mergeStrategy: "deep",
1229
- eventBindingSteps: ["titleDescription", "blockHeight", "linkageRules"],
1228
+ eventBindingSteps: BLOCK_CARD_SETTINGS_GROUP.eventBindingSteps,
1230
1229
  pathSchemas: {
1231
- "titleDescription.title": STRING_SCHEMA,
1232
- "titleDescription.description": STRING_SCHEMA,
1233
- "blockHeight.heightMode": STRING_SCHEMA,
1234
- "blockHeight.height": NUMBER_SCHEMA,
1235
- linkageRules: ARRAY_SCHEMA
1230
+ ...BLOCK_CARD_SETTINGS_GROUP.pathSchemas
1236
1231
  }
1237
1232
  };
1238
1233
  const CHART_BLOCK_CONTRACT = createContract({
@@ -1294,8 +1289,7 @@ JS_BLOCK_CONTRACT.domains.stepParams = groupedDomain({
1294
1289
  });
1295
1290
  const MAP_BLOCK_CONTRACT = createContract({
1296
1291
  editableDomains: ["props", "decoratorProps", "stepParams", "flowRegistry"],
1297
- props: ["height", "heightMode", "mapField", "marker", "lineSort", "zoom"],
1298
- decoratorProps: ["height", "heightMode"],
1292
+ props: ["mapField", "marker", "lineSort", "zoom"],
1299
1293
  stepParams: ["resourceSettings", "createMapBlock", "cardSettings"],
1300
1294
  flowRegistry: true,
1301
1295
  eventCapabilities: {
@@ -113,4 +113,4 @@ export declare function compileComposeExecutionPlan(input: {
113
113
  layout?: FlowSurfaceComposeObject;
114
114
  }): FlowSurfaceCompiledComposePlan;
115
115
  export declare function resolveComposeFieldContainerSource(blockSpec: Pick<FlowSurfaceComposeNormalizedBlockSpec, 'type'>): 'block' | 'item';
116
- export declare function resolveComposeTargetKey(targetKey: string, keyMap: Record<string, FlowSurfaceComposeTargetKey | undefined>, kind: 'field' | 'layout'): string;
116
+ export declare function resolveComposeTargetKey(targetKey: string, keyMap: Record<string, FlowSurfaceComposeTargetKey | undefined>, kind: 'field' | 'layout' | 'tree connectFields'): string;
@@ -66,6 +66,7 @@ export type FlowSurfaceComposeRuntimeDeps = {
66
66
  removeExistingItem?: (uid: string) => Promise<void>;
67
67
  createBlock: (payload: Record<string, unknown>, spec: FlowSurfaceComposeNormalizedBlockSpec) => Promise<FlowSurfaceComposeBlockResult>;
68
68
  applyNodeSettings?: (actionName: string, targetUid: string | undefined, settings?: FlowSurfaceComposeObject) => Promise<void>;
69
+ resolveBlockSettings?: (settings: FlowSurfaceComposeObject, state: FlowSurfaceComposeRuntimeState, block: FlowSurfaceComposeRuntimeBlockState) => FlowSurfaceComposeObject | Promise<FlowSurfaceComposeObject>;
69
70
  createField: (payload: Record<string, unknown>, spec: FlowSurfaceComposeNormalizedFieldSpec, blockResult: FlowSurfaceComposeBlockResult) => Promise<FlowSurfaceComposeFieldResult | null>;
70
71
  applyFieldSettings?: (actionName: string, result: FlowSurfaceComposeFieldResult, settings?: FlowSurfaceComposeObject) => Promise<void>;
71
72
  onFieldError?: (input: {
@@ -142,7 +142,8 @@ async function applyBlockSettings(deps, state) {
142
142
  if (!hasInlineSettings(block.spec.settings)) {
143
143
  continue;
144
144
  }
145
- await applyNodeSettings("compose block", block.result.uid, block.spec.settings);
145
+ const settings = deps.resolveBlockSettings ? await deps.resolveBlockSettings(block.spec.settings || {}, state, block) : block.spec.settings;
146
+ await applyNodeSettings("compose block", block.result.uid, settings);
146
147
  }
147
148
  }
148
149
  async function createFields(plan, deps, state) {
@@ -80,6 +80,16 @@ const SORTING = arrayOption("Sorting rule array", {
80
80
  }
81
81
  ]
82
82
  });
83
+ const CONNECT_FIELDS = objectOption("Tree connect data block targets", {
84
+ example: {
85
+ targets: [
86
+ {
87
+ targetId: "target-block-uid",
88
+ filterPaths: ["id"]
89
+ }
90
+ ]
91
+ }
92
+ });
83
93
  const OPEN_VIEW = objectOption("Popup or drawer open configuration", {
84
94
  example: {
85
95
  dataSourceKey: "main",
@@ -247,7 +257,8 @@ const TREE_OPTIONS = {
247
257
  fieldNames: objectOption("Tree field names", { example: { title: "title", key: "id", children: "children" } }),
248
258
  pageSize: numberOption("Root records per page", { example: 200 }),
249
259
  dataScope: FILTER_GROUP,
250
- sorting: SORTING
260
+ sorting: SORTING,
261
+ connectFields: CONNECT_FIELDS
251
262
  };
252
263
  const KANBAN_OPTIONS = {
253
264
  ...COMMON_BLOCK_HEADER_OPTIONS,
@@ -103,7 +103,7 @@ const FIELD_BINDING_RULE_DEFINITIONS = [
103
103
  {
104
104
  scope: "display",
105
105
  modelClassName: "DisplayPreviewFieldModel",
106
- interfaces: ["url", "attachment", "attachmentURL", "m2m", "m2o", "o2o", "o2m", "oho", "obo", "mbm"],
106
+ interfaces: ["attachment", "attachmentURL", "m2m", "m2o", "o2o", "o2m", "oho", "obo", "mbm"],
107
107
  ownerPlugin: FILE_MANAGER_PLUGIN,
108
108
  isDefault: true,
109
109
  when: ({ field, targetCollection }) => isAttachmentInterface(field) || !targetCollection || getCollectionTemplate(targetCollection) === "file"
@@ -155,8 +155,8 @@ function getFieldName(field) {
155
155
  return (field == null ? void 0 : field.name) || ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.name);
156
156
  }
157
157
  function getFieldTitle(field) {
158
- var _a;
159
- return (field == null ? void 0 : field.title) || ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.title) || getFieldName(field);
158
+ var _a, _b, _c, _d;
159
+ return ((_a = field == null ? void 0 : field.uiSchema) == null ? void 0 : _a.title) || ((_c = (_b = field == null ? void 0 : field.options) == null ? void 0 : _b.uiSchema) == null ? void 0 : _c.title) || (field == null ? void 0 : field.title) || ((_d = field == null ? void 0 : field.options) == null ? void 0 : _d.title) || getFieldName(field);
160
160
  }
161
161
  function resolveAssociationNameFromField(field, fallbackCollection) {
162
162
  const resourceName = typeof (field == null ? void 0 : field.resourceName) === "string" ? field.resourceName.trim() : "";
@@ -21,6 +21,7 @@ export declare function normalizeBlockTitleDescription(titleDescription: any): a
21
21
  export declare function buildBlockTitleDescriptionFromSemanticChanges(changes: Record<string, any>): {
22
22
  titleDescription: _.Dictionary<any>;
23
23
  };
24
+ export declare function buildBlockCardSettingsFromSemanticChanges(changes: Record<string, any>): {};
24
25
  export declare function buildChartCardSettingsFromSemanticChanges(currentCardSettings: any, changes: Record<string, any>): any;
25
26
  export declare function buildPopupTabTree(options: {
26
27
  tabUid?: string;
@@ -38,6 +38,7 @@ var service_utils_exports = {};
38
38
  __export(service_utils_exports, {
39
39
  assertFlowSurfaceComposeUniqueKeys: () => assertFlowSurfaceComposeUniqueKeys,
40
40
  assertSupportedSimpleChanges: () => assertSupportedSimpleChanges,
41
+ buildBlockCardSettingsFromSemanticChanges: () => buildBlockCardSettingsFromSemanticChanges,
41
42
  buildBlockTitleDescriptionFromSemanticChanges: () => buildBlockTitleDescriptionFromSemanticChanges,
42
43
  buildChartCardSettingsFromSemanticChanges: () => buildChartCardSettingsFromSemanticChanges,
43
44
  buildDefaultFieldState: () => buildDefaultFieldState,
@@ -180,6 +181,25 @@ function buildBlockTitleDescriptionFromSemanticChanges(changes) {
180
181
  })
181
182
  };
182
183
  }
184
+ function buildBlockCardSettingsFromSemanticChanges(changes) {
185
+ const nextCardSettings = buildBlockTitleDescriptionFromSemanticChanges(changes) || {};
186
+ const hasHeightPatch = hasOwnDefined(changes, "height") || hasOwnDefined(changes, "heightMode");
187
+ if (hasHeightPatch) {
188
+ const nextHeightMode = hasOwnDefined(changes, "heightMode") ? normalizePublicBlockHeightMode(changes.heightMode) : hasOwnDefined(changes, "height") ? "specifyValue" : void 0;
189
+ if (nextHeightMode) {
190
+ import_lodash.default.set(nextCardSettings, ["blockHeight", "heightMode"], nextHeightMode);
191
+ if (nextHeightMode === "specifyValue" && hasOwnDefined(changes, "height")) {
192
+ import_lodash.default.set(nextCardSettings, ["blockHeight", "height"], changes.height);
193
+ } else {
194
+ import_lodash.default.unset(nextCardSettings, ["blockHeight", "height"]);
195
+ }
196
+ }
197
+ }
198
+ if (import_lodash.default.isEmpty(import_lodash.default.get(nextCardSettings, ["blockHeight"]))) {
199
+ import_lodash.default.unset(nextCardSettings, ["blockHeight"]);
200
+ }
201
+ return Object.keys(nextCardSettings).length ? nextCardSettings : void 0;
202
+ }
183
203
  function buildChartCardSettingsFromSemanticChanges(currentCardSettings, changes) {
184
204
  const nextCardSettings = import_lodash.default.cloneDeep(currentCardSettings || {});
185
205
  const currentTitleDescription = import_lodash.default.get(currentCardSettings, ["titleDescription"]);
@@ -820,6 +840,7 @@ function getFieldBindingDefaultProps(containerUse, fieldUse, field) {
820
840
  0 && (module.exports = {
821
841
  assertFlowSurfaceComposeUniqueKeys,
822
842
  assertSupportedSimpleChanges,
843
+ buildBlockCardSettingsFromSemanticChanges,
823
844
  buildBlockTitleDescriptionFromSemanticChanges,
824
845
  buildChartCardSettingsFromSemanticChanges,
825
846
  buildDefaultFieldState,
@@ -484,6 +484,7 @@ export declare class FlowSurfacesService {
484
484
  private buildDefaultFieldOpenView;
485
485
  private ensureLocalFieldPopupSurface;
486
486
  private applyInlineNodeSettings;
487
+ private resolveComposeBlockSettings;
487
488
  private applyInlineFieldPopup;
488
489
  private applyInlineFieldSettings;
489
490
  private applyInlineStandaloneFieldSettings;
@@ -543,7 +544,6 @@ export declare class FlowSurfacesService {
543
544
  private normalizeCanonicalBlockHeaderWriteForUpdateSettings;
544
545
  private syncCanonicalBlockHeaderForUpdateSettings;
545
546
  private stripLegacyBlockHeaderChromeForUpdateSettings;
546
- private syncMapHeightChromeForUpdateSettings;
547
547
  private normalizeOpenViewForUpdateSettings;
548
548
  private syncChartConfigureForUpdateSettings;
549
549
  private validateChartConfigureForUpdateSettings;
@@ -704,10 +704,18 @@ export declare class FlowSurfacesService {
704
704
  private buildFieldCatalogEntriesForResource;
705
705
  private buildLegacyFieldCatalogEntriesForResource;
706
706
  private findOwningBlockGrid;
707
+ private assertNoTreeConnectFieldsFlowRegistry;
708
+ private normalizeTreeConnectFields;
709
+ private getDataBlockResourceInit;
710
+ private getTreeSelectedKeyFieldPath;
711
+ private normalizeTreeConnectFilterPaths;
712
+ private resolveTreeConnectComparableField;
713
+ private normalizeTreeConnectValueKind;
714
+ private persistTreeConnectFields;
707
715
  private isFilterFormFieldPathAvailableForResource;
708
716
  private persistFilterFormConnectConfig;
709
- private removeFilterFormConnectConfig;
710
- private removeFilterFormTargetBindings;
717
+ private removeFilterSourceBindings;
718
+ private removeFilterTargetBindings;
711
719
  private collectChartBlockUidsFromTree;
712
720
  private removeFlowSqlBindingsForChartUids;
713
721
  private removeFlowSqlBindingsForNodeTree;
@@ -166,6 +166,7 @@ const FILTER_TARGET_BLOCK_USES = /* @__PURE__ */ new Set([
166
166
  "MapBlockModel",
167
167
  "CommentsBlockModel"
168
168
  ]);
169
+ const TREE_CONNECT_TARGET_BLOCK_USES = new Set(FILTER_TARGET_BLOCK_USES);
169
170
  const EDITABLE_FIELD_WRAPPER_USES = /* @__PURE__ */ new Set(["FormItemModel", "FilterFormItemModel", "PatternFormItemModel"]);
170
171
  const DISPLAY_FIELD_WRAPPER_USES = /* @__PURE__ */ new Set([
171
172
  "DetailsItemModel",
@@ -1026,27 +1027,36 @@ class FlowSurfacesService {
1026
1027
  });
1027
1028
  }
1028
1029
  collectRelationNestedFieldPaths(fieldNode) {
1029
- var _a, _b, _c, _d, _e, _f, _g;
1030
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1030
1031
  const fieldUse = String(((_b = (_a = fieldNode == null ? void 0 : fieldNode.stepParams) == null ? void 0 : _a.fieldBinding) == null ? void 0 : _b.use) || (fieldNode == null ? void 0 : fieldNode.use) || "").trim();
1032
+ const relationFieldInit = ((_d = (_c = fieldNode == null ? void 0 : fieldNode.stepParams) == null ? void 0 : _c.fieldSettings) == null ? void 0 : _d.init) || {};
1033
+ const relationFieldPath = (0, import_service_helpers.normalizeFieldPath)(relationFieldInit.fieldPath, relationFieldInit.associationPathName);
1034
+ const toPublicFieldPath = (fieldPath) => {
1035
+ const normalized = String(fieldPath || "").trim();
1036
+ if (!normalized || !relationFieldPath || !normalized.startsWith(`${relationFieldPath}.`)) {
1037
+ return normalized;
1038
+ }
1039
+ return normalized.slice(relationFieldPath.length + 1);
1040
+ };
1031
1041
  if (["SubTableFieldModel", "DisplaySubTableFieldModel"].includes(fieldUse)) {
1032
- return import_lodash.default.castArray(((_c = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _c.columns) || []).map((item) => {
1042
+ return import_lodash.default.castArray(((_e = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _e.columns) || []).map((item) => {
1033
1043
  var _a2, _b2, _c2;
1034
1044
  return (_c2 = (_b2 = (_a2 = item == null ? void 0 : item.stepParams) == null ? void 0 : _a2.fieldSettings) == null ? void 0 : _b2.init) == null ? void 0 : _c2.fieldPath;
1035
- }).filter(Boolean);
1045
+ }).map(toPublicFieldPath).filter(Boolean);
1036
1046
  }
1037
1047
  if (fieldUse === "PopupSubTableFieldModel") {
1038
- return import_lodash.default.castArray(((_d = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _d.subTableColumns) || []).filter((item) => (item == null ? void 0 : item.use) === "TableColumnModel").map((item) => {
1048
+ return import_lodash.default.castArray(((_f = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _f.subTableColumns) || []).filter((item) => (item == null ? void 0 : item.use) === "TableColumnModel").map((item) => {
1039
1049
  var _a2, _b2, _c2;
1040
1050
  return (_c2 = (_b2 = (_a2 = item == null ? void 0 : item.stepParams) == null ? void 0 : _a2.fieldSettings) == null ? void 0 : _b2.init) == null ? void 0 : _c2.fieldPath;
1041
- }).filter(Boolean);
1051
+ }).map(toPublicFieldPath).filter(Boolean);
1042
1052
  }
1043
1053
  if (["SubFormFieldModel", "SubFormListFieldModel", "DisplaySubItemFieldModel", "DisplaySubListFieldModel"].includes(
1044
1054
  fieldUse
1045
1055
  )) {
1046
- return import_lodash.default.castArray(((_g = (_f = (_e = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _e.grid) == null ? void 0 : _f.subModels) == null ? void 0 : _g.items) || []).map((item) => {
1056
+ return import_lodash.default.castArray(((_i = (_h = (_g = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _g.grid) == null ? void 0 : _h.subModels) == null ? void 0 : _i.items) || []).map((item) => {
1047
1057
  var _a2, _b2, _c2;
1048
1058
  return (_c2 = (_b2 = (_a2 = item == null ? void 0 : item.stepParams) == null ? void 0 : _a2.fieldSettings) == null ? void 0 : _b2.init) == null ? void 0 : _c2.fieldPath;
1049
- }).filter(Boolean);
1059
+ }).map(toPublicFieldPath).filter(Boolean);
1050
1060
  }
1051
1061
  return void 0;
1052
1062
  }
@@ -3821,6 +3831,7 @@ class FlowSurfacesService {
3821
3831
  }
3822
3832
  await this.applyInlineNodeSettings(actionName, targetUid, settings, options);
3823
3833
  },
3834
+ resolveBlockSettings: (settings, state) => this.resolveComposeBlockSettings(settings, state.keyMap),
3824
3835
  createField: async (payload) => this.addField(payload, {
3825
3836
  ...options,
3826
3837
  popupTemplateAliasSession
@@ -5472,6 +5483,7 @@ class FlowSurfacesService {
5472
5483
  fieldUid: tree.innerUid,
5473
5484
  fieldUse: boundFieldCapability.fieldUse,
5474
5485
  targetCollection: relationFieldTypeResolution.targetCollection,
5486
+ relationFieldInit: normalizedFieldBinding,
5475
5487
  fields: relationFieldTypeResolution.fields,
5476
5488
  selectorFields: relationFieldTypeResolution.selectorFields,
5477
5489
  titleField: relationFieldTypeResolution.titleField,
@@ -6783,6 +6795,27 @@ class FlowSurfacesService {
6783
6795
  (0, import_service_utils.rethrowInlineConfigurationError)(error, `flowSurfaces ${actionName} settings invalid`);
6784
6796
  }
6785
6797
  }
6798
+ resolveComposeBlockSettings(settings, keyMap) {
6799
+ if (!import_lodash.default.isPlainObject(settings == null ? void 0 : settings.connectFields) || !Array.isArray(settings.connectFields.targets)) {
6800
+ return settings;
6801
+ }
6802
+ const nextSettings = import_lodash.default.cloneDeep(settings);
6803
+ nextSettings.connectFields = {
6804
+ ...nextSettings.connectFields,
6805
+ targets: import_lodash.default.castArray(nextSettings.connectFields.targets).map((target) => {
6806
+ if (!import_lodash.default.isPlainObject(target) || import_lodash.default.isUndefined(target.target) || target.target === null || target.target === "") {
6807
+ return target;
6808
+ }
6809
+ const nextTarget = {
6810
+ ...target,
6811
+ targetId: (0, import_compose_compiler.resolveComposeTargetKey)(String(target.target), keyMap, "tree connectFields")
6812
+ };
6813
+ delete nextTarget.target;
6814
+ return nextTarget;
6815
+ })
6816
+ };
6817
+ return nextSettings;
6818
+ }
6786
6819
  async applyInlineFieldPopup(actionName, result, popup, options) {
6787
6820
  popup = this.prepareInlinePopupTemplateAliases(actionName, popup, options.popupTemplateAliasSession);
6788
6821
  const fieldHostUid = result.fieldUid || result.uid;
@@ -7830,6 +7863,9 @@ class FlowSurfacesService {
7830
7863
  if (typeof normalizedValues[domain] === "undefined") {
7831
7864
  return;
7832
7865
  }
7866
+ if (domain === "flowRegistry") {
7867
+ this.assertNoTreeConnectFieldsFlowRegistry(current, normalizedValues[domain], "updateSettings");
7868
+ }
7833
7869
  if (!contract.editableDomains.includes(domain)) {
7834
7870
  (0, import_errors.throwBadRequest)(`flowSurfaces updateSettings domain '${domain}' is not editable`);
7835
7871
  }
@@ -7861,7 +7897,6 @@ class FlowSurfacesService {
7861
7897
  this.syncChartConfigureForUpdateSettings(current, nextPayload);
7862
7898
  await this.validateChartConfigureForUpdateSettings(current, nextPayload, options.transaction);
7863
7899
  this.syncCanonicalBlockHeaderForUpdateSettings(current, nextPayload);
7864
- this.syncMapHeightChromeForUpdateSettings(current, nextPayload);
7865
7900
  this.syncChartCardRuntimeStepParamsForUpdateSettings(
7866
7901
  current,
7867
7902
  nextPayload,
@@ -8052,6 +8087,7 @@ class FlowSurfacesService {
8052
8087
  import_lodash.default.set(values, titleDescriptionPath, normalizedTitleDescription);
8053
8088
  }
8054
8089
  syncCanonicalBlockHeaderForUpdateSettings(current, nextPayload) {
8090
+ var _a;
8055
8091
  const semanticUse = (0, import_approval.normalizeApprovalSemanticUse)(current == null ? void 0 : current.use);
8056
8092
  if (!CANONICAL_BLOCK_HEADER_USES.has(semanticUse)) {
8057
8093
  return;
@@ -8062,11 +8098,19 @@ class FlowSurfacesService {
8062
8098
  const nextStepParams = import_lodash.default.cloneDeep(nextPayload.stepParams ?? (current == null ? void 0 : current.stepParams) ?? {});
8063
8099
  const nextCardSettings = import_lodash.default.cloneDeep(import_lodash.default.get(nextStepParams, ["cardSettings"]) || {});
8064
8100
  const normalizedTitleDescription = (0, import_service_utils.normalizeBlockTitleDescription)(import_lodash.default.get(nextCardSettings, ["titleDescription"]));
8101
+ const normalizedBlockHeight = (_a = (0, import_service_utils.normalizeChartCardSettings)({
8102
+ blockHeight: import_lodash.default.get(nextCardSettings, ["blockHeight"])
8103
+ })) == null ? void 0 : _a.blockHeight;
8065
8104
  if (normalizedTitleDescription) {
8066
8105
  import_lodash.default.set(nextCardSettings, ["titleDescription"], normalizedTitleDescription);
8067
8106
  } else {
8068
8107
  import_lodash.default.unset(nextCardSettings, ["titleDescription"]);
8069
8108
  }
8109
+ if (normalizedBlockHeight) {
8110
+ import_lodash.default.set(nextCardSettings, ["blockHeight"], normalizedBlockHeight);
8111
+ } else {
8112
+ import_lodash.default.unset(nextCardSettings, ["blockHeight"]);
8113
+ }
8070
8114
  if (import_lodash.default.isEmpty(nextCardSettings)) {
8071
8115
  import_lodash.default.unset(nextStepParams, ["cardSettings"]);
8072
8116
  } else {
@@ -8100,28 +8144,6 @@ class FlowSurfacesService {
8100
8144
  );
8101
8145
  }
8102
8146
  }
8103
- syncMapHeightChromeForUpdateSettings(current, nextPayload) {
8104
- if ((current == null ? void 0 : current.use) !== "MapBlockModel") {
8105
- return;
8106
- }
8107
- const nextProps = import_lodash.default.isPlainObject(nextPayload.props) ? nextPayload.props : void 0;
8108
- if (!nextProps) {
8109
- return;
8110
- }
8111
- const nextDecoratorProps = import_lodash.default.cloneDeep(nextPayload.decoratorProps ?? (current == null ? void 0 : current.decoratorProps) ?? {});
8112
- let changed = false;
8113
- if (Object.prototype.hasOwnProperty.call(nextProps, "height") && nextDecoratorProps.height !== nextProps.height) {
8114
- nextDecoratorProps.height = nextProps.height;
8115
- changed = true;
8116
- }
8117
- if (Object.prototype.hasOwnProperty.call(nextProps, "heightMode") && nextDecoratorProps.heightMode !== nextProps.heightMode) {
8118
- nextDecoratorProps.heightMode = nextProps.heightMode;
8119
- changed = true;
8120
- }
8121
- if (changed) {
8122
- nextPayload.decoratorProps = (0, import_service_utils.buildDefinedPayload)(nextDecoratorProps);
8123
- }
8124
- }
8125
8147
  async normalizeOpenViewForUpdateSettings(actionName, current, nextPayload, options = {}) {
8126
8148
  const openViewPaths = [
8127
8149
  ["popupSettings", "openView"],
@@ -8389,6 +8411,7 @@ class FlowSurfacesService {
8389
8411
  (0, import_errors.throwBadRequest)(`flowSurfaces setEventFlows is not supported on '${(current == null ? void 0 : current.use) || target.uid}'`);
8390
8412
  }
8391
8413
  const flows = values.flowRegistry || values.flows || {};
8414
+ this.assertNoTreeConnectFieldsFlowRegistry(current, flows, "setEventFlows");
8392
8415
  this.contractGuard.validateFlowRegistry(current, flows);
8393
8416
  if (target.kind === "tab" && target.tabRoute) {
8394
8417
  await this.routeSync.persistTabSettings(
@@ -8504,10 +8527,13 @@ class FlowSurfacesService {
8504
8527
  });
8505
8528
  this.assertRemoveNodeResolvedTarget(resolved, node);
8506
8529
  if ((node == null ? void 0 : node.use) === "FilterFormItemModel") {
8507
- await this.removeFilterFormConnectConfig(resolved.uid, options.transaction);
8530
+ await this.removeFilterSourceBindings(resolved.uid, options.transaction);
8531
+ }
8532
+ if ((node == null ? void 0 : node.use) === "TreeBlockModel") {
8533
+ await this.removeFilterSourceBindings(resolved.uid, options.transaction);
8508
8534
  }
8509
8535
  if (FILTER_TARGET_BLOCK_USES.has((node == null ? void 0 : node.use) || "")) {
8510
- await this.removeFilterFormTargetBindings(resolved.uid, options.transaction);
8536
+ await this.removeFilterTargetBindings(resolved.uid, options.transaction);
8511
8537
  }
8512
8538
  const approvalRoot = await this.findApprovalSurfaceRootForNode(resolved.uid, options.transaction);
8513
8539
  await this.removeNodeTreeWithBindings(resolved.uid, options.transaction);
@@ -9976,10 +10002,13 @@ class FlowSurfacesService {
9976
10002
  }
9977
10003
  }
9978
10004
  if (node.use === "FilterFormItemModel") {
9979
- await this.removeFilterFormConnectConfig(node.uid, transaction);
10005
+ await this.removeFilterSourceBindings(node.uid, transaction);
10006
+ }
10007
+ if (node.use === "TreeBlockModel") {
10008
+ await this.removeFilterSourceBindings(node.uid, transaction);
9980
10009
  }
9981
10010
  if (FILTER_TARGET_BLOCK_USES.has(node.use || "")) {
9982
- await this.removeFilterFormTargetBindings(node.uid, transaction);
10011
+ await this.removeFilterTargetBindings(node.uid, transaction);
9983
10012
  }
9984
10013
  }
9985
10014
  async configurePage(target, changes, options) {
@@ -10047,15 +10076,11 @@ class FlowSurfacesService {
10047
10076
  }
10048
10077
  async configureTableBlock(target, changes, options) {
10049
10078
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("TableBlockModel");
10050
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10079
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10051
10080
  (0, import_service_utils.assertSupportedSimpleChanges)("table", changes, allowedKeys);
10052
10081
  return this.updateSettings(
10053
10082
  {
10054
10083
  target,
10055
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10056
- height: changes.height,
10057
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10058
- }),
10059
10084
  stepParams: {
10060
10085
  ...cardSettings ? { cardSettings } : {},
10061
10086
  ...changes.resource ? {
@@ -10096,7 +10121,7 @@ class FlowSurfacesService {
10096
10121
  async configureCalendarBlock(target, current, changes, options) {
10097
10122
  var _a;
10098
10123
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("CalendarBlockModel");
10099
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10124
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10100
10125
  (0, import_service_utils.assertSupportedSimpleChanges)("calendar", changes, allowedKeys);
10101
10126
  this.validateCalendarSettingValues("configure", {
10102
10127
  defaultView: changes.defaultView,
@@ -10149,10 +10174,6 @@ class FlowSurfacesService {
10149
10174
  quickCreatePopupSettings,
10150
10175
  eventPopupSettings
10151
10176
  }),
10152
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10153
- height: changes.height,
10154
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10155
- }),
10156
10177
  stepParams: {
10157
10178
  ...cardSettings ? { cardSettings } : {},
10158
10179
  ...changes.resource ? {
@@ -10199,14 +10220,14 @@ class FlowSurfacesService {
10199
10220
  async configureTreeBlock(target, current, changes, options) {
10200
10221
  var _a, _b;
10201
10222
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("TreeBlockModel");
10202
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10223
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10203
10224
  (0, import_service_utils.assertSupportedSimpleChanges)("tree", changes, allowedKeys);
10204
10225
  const nextFieldNames = import_lodash.default.isPlainObject(changes.fieldNames) ? import_lodash.default.merge({}, ((_a = current == null ? void 0 : current.props) == null ? void 0 : _a.fieldNames) || {}, changes.fieldNames) : import_lodash.default.cloneDeep(((_b = current == null ? void 0 : current.props) == null ? void 0 : _b.fieldNames) || {});
10205
10226
  if ((0, import_service_utils.hasOwnDefined)(changes, "titleField")) {
10206
10227
  nextFieldNames.title = String(changes.titleField || "").trim();
10207
10228
  }
10208
10229
  const hasFieldNamesPatch = (0, import_service_utils.hasOwnDefined)(changes, "titleField") || import_lodash.default.isPlainObject(changes.fieldNames);
10209
- return this.updateSettings(
10230
+ const result = await this.updateSettings(
10210
10231
  {
10211
10232
  target,
10212
10233
  props: (0, import_service_utils.buildDefinedPayload)({
@@ -10216,10 +10237,6 @@ class FlowSurfacesService {
10216
10237
  ...hasFieldNamesPatch ? { fieldNames: nextFieldNames } : {},
10217
10238
  ...(0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? { pageSize: changes.pageSize } : {}
10218
10239
  }),
10219
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10220
- height: changes.height,
10221
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10222
- }),
10223
10240
  stepParams: {
10224
10241
  ...cardSettings ? { cardSettings } : {},
10225
10242
  ...changes.resource ? {
@@ -10250,11 +10267,43 @@ class FlowSurfacesService {
10250
10267
  },
10251
10268
  options
10252
10269
  );
10270
+ if ((0, import_service_utils.hasOwnDefined)(changes, "connectFields")) {
10271
+ const effectiveTreeNode = changes.resource || hasFieldNamesPatch || (0, import_service_utils.hasDefinedValue)(changes, [
10272
+ "searchable",
10273
+ "defaultExpandAll",
10274
+ "includeDescendants",
10275
+ "titleField",
10276
+ "pageSize",
10277
+ "dataScope",
10278
+ "sorting"
10279
+ ]) ? await this.repository.findModelById(current.uid, {
10280
+ transaction: options.transaction,
10281
+ includeAsyncNode: true
10282
+ }) : current;
10283
+ await this.persistTreeConnectFields(
10284
+ effectiveTreeNode,
10285
+ changes.connectFields,
10286
+ "configure tree",
10287
+ options.transaction
10288
+ );
10289
+ return {
10290
+ ...result,
10291
+ updated: import_lodash.default.uniq([...result.updated || [], "connectFields"])
10292
+ };
10293
+ }
10294
+ if ((0, import_service_utils.hasOwnDefined)(changes, "resource")) {
10295
+ await this.removeFilterSourceBindings(current.uid, options.transaction);
10296
+ return {
10297
+ ...result,
10298
+ updated: import_lodash.default.uniq([...result.updated || [], "connectFields"])
10299
+ };
10300
+ }
10301
+ return result;
10253
10302
  }
10254
10303
  async configureKanbanBlock(target, current, changes, options) {
10255
10304
  var _a;
10256
10305
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("KanbanBlockModel");
10257
- const blockCardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10306
+ const blockCardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10258
10307
  (0, import_service_utils.assertSupportedSimpleChanges)("kanban", changes, allowedKeys);
10259
10308
  if (!import_lodash.default.isUndefined(changes.dragEnabled) && !import_lodash.default.isBoolean(changes.dragEnabled)) {
10260
10309
  (0, import_errors.throwBadRequest)("flowSurfaces configure kanban dragEnabled must be a boolean");
@@ -10533,15 +10582,11 @@ class FlowSurfacesService {
10533
10582
  } : {}
10534
10583
  });
10535
10584
  const updated = /* @__PURE__ */ new Set();
10536
- if (Object.keys(blockProps).length || Object.keys(blockStepParams).length || (0, import_service_utils.hasDefinedValue)(changes, ["height", "heightMode"])) {
10585
+ if (Object.keys(blockProps).length || Object.keys(blockStepParams).length) {
10537
10586
  const blockResult = await this.updateSettings(
10538
10587
  {
10539
10588
  target,
10540
10589
  props: blockProps,
10541
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10542
- height: changes.height,
10543
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10544
- }),
10545
10590
  stepParams: blockStepParams
10546
10591
  },
10547
10592
  options
@@ -10718,16 +10763,12 @@ class FlowSurfacesService {
10718
10763
  }
10719
10764
  async configureListBlock(target, changes, options) {
10720
10765
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("ListBlockModel");
10721
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10766
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10722
10767
  (0, import_service_utils.assertSupportedSimpleChanges)("list", changes, allowedKeys);
10723
10768
  const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
10724
10769
  return this.updateSettings(
10725
10770
  {
10726
10771
  target,
10727
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10728
- height: changes.height,
10729
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10730
- }),
10731
10772
  stepParams: {
10732
10773
  ...cardSettings ? { cardSettings } : {},
10733
10774
  ...changes.resource ? {
@@ -10750,17 +10791,13 @@ class FlowSurfacesService {
10750
10791
  }
10751
10792
  async configureGridCardBlock(target, changes, options) {
10752
10793
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("GridCardBlockModel");
10753
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10794
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10754
10795
  (0, import_service_utils.assertSupportedSimpleChanges)("gridCard", changes, allowedKeys);
10755
10796
  const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
10756
10797
  const columns = (0, import_service_utils.normalizeGridCardColumns)(changes.columns);
10757
10798
  return this.updateSettings(
10758
10799
  {
10759
10800
  target,
10760
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10761
- height: changes.height,
10762
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10763
- }),
10764
10801
  stepParams: {
10765
10802
  ...cardSettings ? { cardSettings } : {},
10766
10803
  ...changes.resource ? {
@@ -10929,15 +10966,11 @@ class FlowSurfacesService {
10929
10966
  }
10930
10967
  async configureMapBlock(target, changes, options) {
10931
10968
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("MapBlockModel");
10932
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10969
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10933
10970
  (0, import_service_utils.assertSupportedSimpleChanges)("map", changes, allowedKeys);
10934
10971
  return this.updateSettings(
10935
10972
  {
10936
10973
  target,
10937
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10938
- height: changes.height,
10939
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10940
- }),
10941
10974
  stepParams: (0, import_service_utils.buildDefinedPayload)({
10942
10975
  ...cardSettings ? { cardSettings } : {},
10943
10976
  ...changes.resource ? {
@@ -11292,6 +11325,7 @@ class FlowSurfacesService {
11292
11325
  fieldUid: innerUid,
11293
11326
  fieldUse: normalizedFieldComponentUse,
11294
11327
  targetCollection: fieldTypeResolution.targetCollection,
11328
+ relationFieldInit: fieldSource.fieldSettingsInit,
11295
11329
  fields: (0, import_service_utils.hasOwnDefined)(changes, "fields") || shouldApplyFieldTypeDefaults ? fieldTypeResolution.fields : void 0,
11296
11330
  selectorFields: (0, import_service_utils.hasOwnDefined)(changes, "selectorFields") || shouldApplyFieldTypeDefaults ? fieldTypeResolution.selectorFields : void 0,
11297
11331
  titleField: relationTitleFieldToApply,
@@ -12233,6 +12267,222 @@ class FlowSurfacesService {
12233
12267
  }
12234
12268
  return null;
12235
12269
  }
12270
+ assertNoTreeConnectFieldsFlowRegistry(node, flowRegistry, actionName) {
12271
+ if ((node == null ? void 0 : node.use) !== "TreeBlockModel" || !import_lodash.default.isPlainObject(flowRegistry) || !Object.prototype.hasOwnProperty.call(flowRegistry, "connectFields")) {
12272
+ return;
12273
+ }
12274
+ (0, import_errors.throwBadRequest)(
12275
+ `flowSurfaces ${actionName} tree connectFields is not a flowRegistry key; use configure changes.connectFields`
12276
+ );
12277
+ }
12278
+ normalizeTreeConnectFields(value, actionName) {
12279
+ if (!import_lodash.default.isPlainObject(value)) {
12280
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} tree connectFields must be an object`);
12281
+ }
12282
+ if (!Array.isArray(value.targets)) {
12283
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} tree connectFields.targets must be an array`);
12284
+ }
12285
+ const seenTargetBlockUids = /* @__PURE__ */ new Set();
12286
+ return value.targets.map((target, targetIndex) => {
12287
+ if (!import_lodash.default.isPlainObject(target)) {
12288
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} tree connectFields.targets[${targetIndex}] must be an object`);
12289
+ }
12290
+ const targetBlockUid = String(target.targetId || target.targetBlockUid || "").trim();
12291
+ if (!targetBlockUid) {
12292
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} tree connectFields.targets[${targetIndex}] requires targetId`);
12293
+ }
12294
+ if (seenTargetBlockUids.has(targetBlockUid)) {
12295
+ (0, import_errors.throwBadRequest)(
12296
+ `flowSurfaces ${actionName} tree connectFields.targets[${targetIndex}] duplicate targetId '${targetBlockUid}'`
12297
+ );
12298
+ }
12299
+ seenTargetBlockUids.add(targetBlockUid);
12300
+ let filterPaths;
12301
+ if ((0, import_service_utils.hasOwnDefined)(target, "filterPaths")) {
12302
+ if (!Array.isArray(target.filterPaths) || !target.filterPaths.length) {
12303
+ (0, import_errors.throwBadRequest)(
12304
+ `flowSurfaces ${actionName} tree connectFields.targets[${targetIndex}].filterPaths must be a non-empty string array`
12305
+ );
12306
+ }
12307
+ filterPaths = target.filterPaths.map((path, pathIndex) => {
12308
+ if (typeof path !== "string" || !path.trim()) {
12309
+ (0, import_errors.throwBadRequest)(
12310
+ `flowSurfaces ${actionName} tree connectFields.targets[${targetIndex}].filterPaths[${pathIndex}] must be a non-empty string`
12311
+ );
12312
+ }
12313
+ return (0, import_service_helpers.normalizeFieldPath)(path);
12314
+ });
12315
+ }
12316
+ return {
12317
+ targetBlockUid,
12318
+ ...filterPaths ? { filterPaths } : {}
12319
+ };
12320
+ });
12321
+ }
12322
+ getDataBlockResourceInit(blockNode) {
12323
+ if ((blockNode == null ? void 0 : blockNode.use) === "ChartBlockModel") {
12324
+ return (0, import_chart_config.getChartBuilderResourceInit)(import_lodash.default.get(blockNode, ["stepParams", "chartSettings", "configure"]));
12325
+ }
12326
+ const init = import_lodash.default.cloneDeep(import_lodash.default.get(blockNode, ["stepParams", "resourceSettings", "init"]) || {});
12327
+ if (init.collectionName && !init.dataSourceKey) {
12328
+ init.dataSourceKey = "main";
12329
+ }
12330
+ return init;
12331
+ }
12332
+ getTreeSelectedKeyFieldPath(treeNode, treeCollection) {
12333
+ const configuredKey = String(import_lodash.default.get(treeNode, ["props", "fieldNames", "key"]) || "").trim();
12334
+ return configuredKey ? (0, import_service_helpers.normalizeFieldPath)(configuredKey) : this.getCollectionFilterTargetKey(treeCollection);
12335
+ }
12336
+ normalizeTreeConnectFilterPaths(input) {
12337
+ var _a, _b, _c, _d, _e, _f, _g;
12338
+ const treeDataSourceKey = String(((_a = input.treeResourceInit) == null ? void 0 : _a.dataSourceKey) || "main").trim();
12339
+ const treeCollectionName = String(((_b = input.treeResourceInit) == null ? void 0 : _b.collectionName) || "").trim();
12340
+ const targetDataSourceKey = String(((_c = input.targetResourceInit) == null ? void 0 : _c.dataSourceKey) || "main").trim();
12341
+ const targetCollectionName = String(((_d = input.targetResourceInit) == null ? void 0 : _d.collectionName) || "").trim();
12342
+ if (!treeCollectionName) {
12343
+ (0, import_errors.throwBadRequest)(
12344
+ `flowSurfaces ${input.actionName} tree block '${((_e = input.treeNode) == null ? void 0 : _e.uid) || "unknown"}' requires resource.collectionName`
12345
+ );
12346
+ }
12347
+ if (!targetCollectionName) {
12348
+ (0, import_errors.throwBadRequest)(
12349
+ `flowSurfaces ${input.actionName} tree connectFields target '${((_f = input.targetNode) == null ? void 0 : _f.uid) || "unknown"}' requires resource.collectionName`
12350
+ );
12351
+ }
12352
+ const targetCollection = this.getCollection(targetDataSourceKey, targetCollectionName);
12353
+ if (!targetCollection) {
12354
+ (0, import_errors.throwBadRequest)(
12355
+ `flowSurfaces ${input.actionName} tree connectFields target collection '${targetDataSourceKey}.${targetCollectionName}' not found`
12356
+ );
12357
+ }
12358
+ const treeCollection = this.getCollection(treeDataSourceKey, treeCollectionName);
12359
+ if (!treeCollection) {
12360
+ (0, import_errors.throwBadRequest)(
12361
+ `flowSurfaces ${input.actionName} tree connectFields source collection '${treeDataSourceKey}.${treeCollectionName}' not found`
12362
+ );
12363
+ }
12364
+ const isSameCollection = treeDataSourceKey === targetDataSourceKey && treeCollectionName === targetCollectionName;
12365
+ const normalizedPaths = input.filterPaths && input.filterPaths.length ? input.filterPaths : isSameCollection ? [this.getCollectionFilterTargetKey(targetCollection)] : void 0;
12366
+ if (!(normalizedPaths == null ? void 0 : normalizedPaths.length)) {
12367
+ (0, import_errors.throwBadRequest)(
12368
+ `flowSurfaces ${input.actionName} tree connectFields target '${((_g = input.targetNode) == null ? void 0 : _g.uid) || "unknown"}' requires filterPaths when target collection differs from tree collection`
12369
+ );
12370
+ }
12371
+ const filterTargetKey = this.getCollectionFilterTargetKey(targetCollection);
12372
+ const treeKeyFieldPath = this.getTreeSelectedKeyFieldPath(input.treeNode, treeCollection);
12373
+ const treeKeyField = this.resolveTreeConnectComparableField(treeCollection, treeKeyFieldPath);
12374
+ const treeKeyKind = this.normalizeTreeConnectValueKind(treeKeyField);
12375
+ return normalizedPaths.map((fieldPath) => {
12376
+ const normalizedFieldPath = (0, import_service_helpers.normalizeFieldPath)(fieldPath);
12377
+ const isBuiltInTargetPath = normalizedFieldPath === "id" || normalizedFieldPath === filterTargetKey;
12378
+ const targetField = this.resolveTreeConnectComparableField(targetCollection, normalizedFieldPath);
12379
+ if (!isBuiltInTargetPath && !targetField) {
12380
+ (0, import_errors.throwBadRequest)(
12381
+ `flowSurfaces ${input.actionName} tree connectFields filterPaths '${normalizedFieldPath}' does not exist on target collection '${targetDataSourceKey}.${targetCollectionName}'`
12382
+ );
12383
+ }
12384
+ const targetKind = this.normalizeTreeConnectValueKind(targetField);
12385
+ if (treeKeyKind && targetKind && treeKeyKind !== targetKind) {
12386
+ (0, import_errors.throwBadRequest)(
12387
+ `flowSurfaces ${input.actionName} tree connectFields filterPaths '${normalizedFieldPath}' is not type-compatible with tree selected key '${treeKeyFieldPath}'`
12388
+ );
12389
+ }
12390
+ return normalizedFieldPath;
12391
+ });
12392
+ }
12393
+ resolveTreeConnectComparableField(collection, fieldPath) {
12394
+ const normalizedFieldPath = (0, import_service_helpers.normalizeFieldPath)(fieldPath);
12395
+ const resolvedField = (0, import_service_helpers.resolveFieldFromCollection)(collection, normalizedFieldPath);
12396
+ if (resolvedField) {
12397
+ return resolvedField;
12398
+ }
12399
+ if (normalizedFieldPath === "id") {
12400
+ return {
12401
+ name: "id",
12402
+ type: "bigInt",
12403
+ interface: "integer"
12404
+ };
12405
+ }
12406
+ return null;
12407
+ }
12408
+ normalizeTreeConnectValueKind(field) {
12409
+ const fieldType = String((0, import_service_helpers.getFieldType)(field) || "").trim().toLowerCase();
12410
+ const fieldInterface = String((0, import_service_helpers.getFieldInterface)(field) || "").trim().toLowerCase();
12411
+ if (["bigint", "integer", "int", "number", "float", "double", "decimal", "real"].includes(fieldType) || ["bigint", "integer", "number", "percent"].includes(fieldInterface)) {
12412
+ return "number";
12413
+ }
12414
+ if (["string", "text", "uid", "uuid", "varchar", "char"].includes(fieldType) || ["input", "textarea", "select", "radiogroup", "url", "email", "phone"].includes(fieldInterface)) {
12415
+ return "string";
12416
+ }
12417
+ if (["date", "datetime", "time"].includes(fieldType) || ["date", "datetime", "time"].includes(fieldInterface)) {
12418
+ return "date";
12419
+ }
12420
+ if (fieldType === "boolean" || fieldInterface === "boolean") {
12421
+ return "boolean";
12422
+ }
12423
+ return void 0;
12424
+ }
12425
+ async persistTreeConnectFields(treeNode, connectFields, actionName, transaction) {
12426
+ if ((treeNode == null ? void 0 : treeNode.use) !== "TreeBlockModel" || !(treeNode == null ? void 0 : treeNode.uid)) {
12427
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} connectFields is only supported on tree blocks`);
12428
+ }
12429
+ const targets = this.normalizeTreeConnectFields(connectFields, actionName);
12430
+ const blockGrid = await this.findOwningBlockGrid(treeNode.uid, transaction);
12431
+ if (!(blockGrid == null ? void 0 : blockGrid.uid)) {
12432
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} tree block '${treeNode.uid}' is not under a block grid`);
12433
+ }
12434
+ const treeResourceInit = this.getDataBlockResourceInit(treeNode);
12435
+ const nextBindings = [];
12436
+ for (const target of targets) {
12437
+ if (target.targetBlockUid === treeNode.uid) {
12438
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} tree connectFields targetId cannot be the tree block itself`);
12439
+ }
12440
+ const targetNode = await this.repository.findModelById(target.targetBlockUid, {
12441
+ transaction,
12442
+ includeAsyncNode: true
12443
+ });
12444
+ if (!(targetNode == null ? void 0 : targetNode.uid)) {
12445
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} tree connectFields targetId '${target.targetBlockUid}' not found`);
12446
+ }
12447
+ if (!TREE_CONNECT_TARGET_BLOCK_USES.has(targetNode.use || "")) {
12448
+ (0, import_errors.throwBadRequest)(
12449
+ `flowSurfaces ${actionName} target '${target.targetBlockUid}' does not support tree connectFields`
12450
+ );
12451
+ }
12452
+ const targetGrid = await this.findOwningBlockGrid(targetNode.uid, transaction);
12453
+ if ((targetGrid == null ? void 0 : targetGrid.uid) !== blockGrid.uid) {
12454
+ (0, import_errors.throwBadRequest)(
12455
+ `flowSurfaces ${actionName} tree connectFields target '${target.targetBlockUid}' must be in the same block grid`
12456
+ );
12457
+ }
12458
+ const targetResourceInit = this.getDataBlockResourceInit(targetNode);
12459
+ nextBindings.push({
12460
+ filterId: treeNode.uid,
12461
+ targetId: targetNode.uid,
12462
+ filterPaths: this.normalizeTreeConnectFilterPaths({
12463
+ actionName,
12464
+ treeNode,
12465
+ treeResourceInit,
12466
+ targetNode,
12467
+ targetResourceInit,
12468
+ filterPaths: target.filterPaths
12469
+ })
12470
+ });
12471
+ }
12472
+ const currentConfigs = import_lodash.default.castArray(blockGrid.filterManager || []);
12473
+ const nextConfigs = currentConfigs.filter((config) => (config == null ? void 0 : config.filterId) !== treeNode.uid);
12474
+ nextConfigs.push(...nextBindings);
12475
+ if (import_lodash.default.isEqual(nextConfigs, currentConfigs)) {
12476
+ return;
12477
+ }
12478
+ await this.repository.patch(
12479
+ {
12480
+ uid: blockGrid.uid,
12481
+ filterManager: nextConfigs
12482
+ },
12483
+ { transaction }
12484
+ );
12485
+ }
12236
12486
  isFilterFormFieldPathAvailableForResource(resourceInit, fieldPath, associationPathName) {
12237
12487
  if (!(resourceInit == null ? void 0 : resourceInit.dataSourceKey) || !(resourceInit == null ? void 0 : resourceInit.collectionName) || !fieldPath) {
12238
12488
  return false;
@@ -12263,7 +12513,7 @@ class FlowSurfacesService {
12263
12513
  { transaction }
12264
12514
  );
12265
12515
  }
12266
- async removeFilterFormConnectConfig(filterModelUid, transaction) {
12516
+ async removeFilterSourceBindings(filterModelUid, transaction) {
12267
12517
  const blockGrid = await this.findOwningBlockGrid(filterModelUid, transaction);
12268
12518
  if (!(blockGrid == null ? void 0 : blockGrid.uid)) {
12269
12519
  return;
@@ -12281,7 +12531,7 @@ class FlowSurfacesService {
12281
12531
  { transaction }
12282
12532
  );
12283
12533
  }
12284
- async removeFilterFormTargetBindings(targetBlockUid, transaction) {
12534
+ async removeFilterTargetBindings(targetBlockUid, transaction) {
12285
12535
  const blockGrid = await this.findOwningBlockGrid(targetBlockUid, transaction);
12286
12536
  if (!(blockGrid == null ? void 0 : blockGrid.uid)) {
12287
12537
  return;
@@ -12382,7 +12632,7 @@ class FlowSurfacesService {
12382
12632
  const fieldInit = import_lodash.default.get(node, ["stepParams", "fieldSettings", "init"]) || {};
12383
12633
  const defaultTargetUid = import_lodash.default.get(node, ["stepParams", "filterFormItemSettings", "init", "defaultTargetUid"]);
12384
12634
  if (!(fieldInit == null ? void 0 : fieldInit.fieldPath) || !defaultTargetUid) {
12385
- await this.removeFilterFormConnectConfig(node.uid, transaction);
12635
+ await this.removeFilterSourceBindings(node.uid, transaction);
12386
12636
  return;
12387
12637
  }
12388
12638
  const parentUid = await this.locator.findParentUid(node.uid, transaction);
@@ -12397,7 +12647,7 @@ class FlowSurfacesService {
12397
12647
  if (!options.skipIfTargetUnavailable) {
12398
12648
  throw error;
12399
12649
  }
12400
- await this.removeFilterFormConnectConfig(node.uid, transaction);
12650
+ await this.removeFilterSourceBindings(node.uid, transaction);
12401
12651
  return null;
12402
12652
  });
12403
12653
  if (!target) {
@@ -12408,7 +12658,7 @@ class FlowSurfacesService {
12408
12658
  fieldInit.fieldPath,
12409
12659
  fieldInit.associationPathName
12410
12660
  )) {
12411
- await this.removeFilterFormConnectConfig(node.uid, transaction);
12661
+ await this.removeFilterSourceBindings(node.uid, transaction);
12412
12662
  return;
12413
12663
  }
12414
12664
  await this.persistFilterFormConnectConfig(
@@ -14348,18 +14598,36 @@ class FlowSurfacesService {
14348
14598
  }
14349
14599
  return field;
14350
14600
  }
14351
- buildRelationTargetFieldInit(collection, fieldPath) {
14601
+ buildRelationTargetFieldInit(input) {
14602
+ var _a, _b, _c, _d, _e, _f;
14603
+ const relationFieldPath = (0, import_service_helpers.normalizeFieldPath)(
14604
+ (_a = input.relationFieldInit) == null ? void 0 : _a.fieldPath,
14605
+ (_b = input.relationFieldInit) == null ? void 0 : _b.associationPathName
14606
+ );
14607
+ if (!relationFieldPath) {
14608
+ return (0, import_service_utils.buildDefinedPayload)({
14609
+ dataSourceKey: ((_c = input.targetCollection) == null ? void 0 : _c.dataSourceKey) || "main",
14610
+ collectionName: (0, import_service_helpers.getCollectionName)(input.targetCollection),
14611
+ fieldPath: input.targetFieldPath
14612
+ });
14613
+ }
14614
+ const targetAssociationPath = input.targetFieldPath.includes(".") ? input.targetFieldPath.split(".").slice(0, -1).join(".") : void 0;
14352
14615
  return (0, import_service_utils.buildDefinedPayload)({
14353
- dataSourceKey: (collection == null ? void 0 : collection.dataSourceKey) || "main",
14354
- collectionName: (0, import_service_helpers.getCollectionName)(collection),
14355
- fieldPath
14616
+ dataSourceKey: ((_d = input.relationFieldInit) == null ? void 0 : _d.dataSourceKey) || ((_e = input.targetCollection) == null ? void 0 : _e.dataSourceKey) || "main",
14617
+ collectionName: ((_f = input.relationFieldInit) == null ? void 0 : _f.collectionName) || (0, import_service_helpers.getCollectionName)(input.targetCollection),
14618
+ fieldPath: `${relationFieldPath}.${input.targetFieldPath}`,
14619
+ associationPathName: targetAssociationPath ? `${relationFieldPath}.${targetAssociationPath}` : void 0
14356
14620
  });
14357
14621
  }
14358
14622
  buildRelationTargetTableColumnNode(input) {
14359
14623
  const field = this.getCollectionFieldOrBadRequest(input.collection, input.fieldPath, "fieldType.fields");
14360
14624
  const fieldUse = input.columnUse === "SubTableColumnModel" ? (0, import_service_helpers.inferFieldMenuEditableFieldUse)((0, import_service_helpers.getFieldInterface)(field)) || "InputFieldModel" : (0, import_service_helpers.inferAssociationLeafDisplayFieldUse)((0, import_service_helpers.getFieldInterface)(field)) || "DisplayTextFieldModel";
14361
14625
  const title = (0, import_service_helpers.getFieldTitle)(field);
14362
- const fieldInit = this.buildRelationTargetFieldInit(input.collection, input.fieldPath);
14626
+ const fieldInit = this.buildRelationTargetFieldInit({
14627
+ targetCollection: input.collection,
14628
+ targetFieldPath: input.fieldPath,
14629
+ relationFieldInit: input.relationFieldInit
14630
+ });
14363
14631
  return {
14364
14632
  uid: (0, import_utils.uid)(),
14365
14633
  use: input.columnUse,
@@ -14403,7 +14671,11 @@ class FlowSurfacesService {
14403
14671
  const field = this.getCollectionFieldOrBadRequest(input.collection, input.fieldPath, "fieldType.fields");
14404
14672
  const fieldUse = input.wrapperUse === "FormItemModel" ? (0, import_service_helpers.inferFieldMenuEditableFieldUse)((0, import_service_helpers.getFieldInterface)(field)) || "InputFieldModel" : (0, import_service_helpers.inferAssociationLeafDisplayFieldUse)((0, import_service_helpers.getFieldInterface)(field)) || "DisplayTextFieldModel";
14405
14673
  const title = (0, import_service_helpers.getFieldTitle)(field);
14406
- const fieldInit = this.buildRelationTargetFieldInit(input.collection, input.fieldPath);
14674
+ const fieldInit = this.buildRelationTargetFieldInit({
14675
+ targetCollection: input.collection,
14676
+ targetFieldPath: input.fieldPath,
14677
+ relationFieldInit: input.relationFieldInit
14678
+ });
14407
14679
  return {
14408
14680
  uid: (0, import_utils.uid)(),
14409
14681
  use: input.wrapperUse,
@@ -14547,7 +14819,8 @@ class FlowSurfacesService {
14547
14819
  (fieldPath) => this.buildRelationTargetTableColumnNode({
14548
14820
  collection: input.targetCollection,
14549
14821
  fieldPath,
14550
- columnUse: input.fieldUse === "SubTableFieldModel" ? "SubTableColumnModel" : "TableColumnModel"
14822
+ columnUse: input.fieldUse === "SubTableFieldModel" ? "SubTableColumnModel" : "TableColumnModel",
14823
+ relationFieldInit: input.relationFieldInit
14551
14824
  })
14552
14825
  ),
14553
14826
  transaction: input.transaction
@@ -14569,7 +14842,8 @@ class FlowSurfacesService {
14569
14842
  (fieldPath) => this.buildRelationTargetTableColumnNode({
14570
14843
  collection: input.targetCollection,
14571
14844
  fieldPath,
14572
- columnUse: "TableColumnModel"
14845
+ columnUse: "TableColumnModel",
14846
+ relationFieldInit: input.relationFieldInit
14573
14847
  })
14574
14848
  )
14575
14849
  ],
@@ -14590,7 +14864,8 @@ class FlowSurfacesService {
14590
14864
  (fieldPath) => this.buildRelationTargetGridItemNode({
14591
14865
  collection: input.targetCollection,
14592
14866
  fieldPath,
14593
- wrapperUse
14867
+ wrapperUse,
14868
+ relationFieldInit: input.relationFieldInit
14594
14869
  })
14595
14870
  ),
14596
14871
  transaction: input.transaction
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName.zh-CN": "前端流引擎",
5
5
  "description": "",
6
6
  "description.zh-CN": "",
7
- "version": "2.1.0-beta.21",
7
+ "version": "2.1.0-beta.23",
8
8
  "main": "./dist/server/index.js",
9
9
  "license": "Apache-2.0",
10
10
  "devDependencies": {
@@ -24,5 +24,5 @@
24
24
  "@nocobase/test": "2.x",
25
25
  "@nocobase/utils": "2.x"
26
26
  },
27
- "gitHead": "324bd82f33fca58e98711688a17ceb65c186b65e"
27
+ "gitHead": "bb4c0d3551bf9eff505b63756dd24a0813231f16"
28
28
  }