@nocobase/plugin-flow-engine 2.1.0-beta.20 → 2.1.0-beta.22

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.
Files changed (37) hide show
  1. package/dist/externalVersion.js +10 -10
  2. package/dist/node_modules/ses/package.json +1 -1
  3. package/dist/node_modules/zod/package.json +1 -1
  4. package/dist/server/flow-surfaces/apply/compiler.js +4 -2
  5. package/dist/server/flow-surfaces/association-interfaces.d.ts +10 -0
  6. package/dist/server/flow-surfaces/association-interfaces.js +39 -0
  7. package/dist/server/flow-surfaces/blueprint/compile-blocks.js +108 -6
  8. package/dist/server/flow-surfaces/blueprint/public-types.d.ts +9 -1
  9. package/dist/server/flow-surfaces/builder.d.ts +27 -1
  10. package/dist/server/flow-surfaces/builder.js +54 -4
  11. package/dist/server/flow-surfaces/catalog.d.ts +1 -0
  12. package/dist/server/flow-surfaces/catalog.js +146 -36
  13. package/dist/server/flow-surfaces/compose-compiler.d.ts +9 -1
  14. package/dist/server/flow-surfaces/compose-compiler.js +8 -0
  15. package/dist/server/flow-surfaces/compose-runtime.d.ts +1 -0
  16. package/dist/server/flow-surfaces/compose-runtime.js +2 -1
  17. package/dist/server/flow-surfaces/configure-options.js +50 -6
  18. package/dist/server/flow-surfaces/default-action-popup.js +2 -2
  19. package/dist/server/flow-surfaces/field-binding-registry.d.ts +1 -0
  20. package/dist/server/flow-surfaces/field-binding-registry.js +6 -1
  21. package/dist/server/flow-surfaces/field-semantics.d.ts +1 -1
  22. package/dist/server/flow-surfaces/field-semantics.js +4 -3
  23. package/dist/server/flow-surfaces/field-type-resolver.d.ts +46 -0
  24. package/dist/server/flow-surfaces/field-type-resolver.js +322 -0
  25. package/dist/server/flow-surfaces/node-use-sets.js +1 -0
  26. package/dist/server/flow-surfaces/service-helpers.js +2 -2
  27. package/dist/server/flow-surfaces/service-utils.d.ts +14 -1
  28. package/dist/server/flow-surfaces/service-utils.js +79 -6
  29. package/dist/server/flow-surfaces/service.d.ts +28 -4
  30. package/dist/server/flow-surfaces/service.js +1158 -116
  31. package/dist/server/flow-surfaces/support-matrix.js +11 -0
  32. package/dist/swagger/flow-surfaces.d.ts +173 -2
  33. package/dist/swagger/flow-surfaces.examples.d.ts +20 -15
  34. package/dist/swagger/flow-surfaces.examples.js +22 -11
  35. package/dist/swagger/flow-surfaces.js +72 -10
  36. package/dist/swagger/index.d.ts +173 -2
  37. package/package.json +2 -2
@@ -64,6 +64,7 @@ var import_created_keys = require("./planning/created-keys");
64
64
  var import_key_persistence = require("./planning/key-persistence");
65
65
  var import_payload_shape = require("./payload-shape");
66
66
  var import_field_semantics = require("./field-semantics");
67
+ var import_association_interfaces = require("./association-interfaces");
67
68
  var import_field_binding_registry = require("./field-binding-registry");
68
69
  var import_node_use_sets = require("./node-use-sets");
69
70
  var import_chart_config = require("./chart-config");
@@ -89,6 +90,7 @@ var import_association_title_field = require("./association-title-field");
89
90
  var import_default_action_popup = require("./default-action-popup");
90
91
  var import_defaults = require("./blueprint/defaults");
91
92
  var import_service_utils = require("./service-utils");
93
+ var import_field_type_resolver = require("./field-type-resolver");
92
94
  var import_template_compatibility = require("./template-compatibility");
93
95
  var import_template_service_utils = require("./template-service-utils");
94
96
  const FORM_BLOCK_USES = /* @__PURE__ */ new Set(["FormBlockModel", "CreateFormModel", "EditFormModel", ...import_approval.APPROVAL_FORM_BLOCK_USES]);
@@ -128,6 +130,7 @@ const KANBAN_POPUP_ACTION_KEYS = Object.keys(KANBAN_POPUP_ACTION_UID_SUFFIX_BY_K
128
130
  const CANONICAL_BLOCK_HEADER_USES = /* @__PURE__ */ new Set([
129
131
  "TableBlockModel",
130
132
  "CalendarBlockModel",
133
+ "TreeBlockModel",
131
134
  "KanbanBlockModel",
132
135
  "FormBlockModel",
133
136
  "CreateFormModel",
@@ -154,6 +157,7 @@ const OPEN_VIEW_SUPPORTED_MODES = /* @__PURE__ */ new Set(["drawer", "dialog", "
154
157
  const FILTER_TARGET_BLOCK_USES = /* @__PURE__ */ new Set([
155
158
  "TableBlockModel",
156
159
  "CalendarBlockModel",
160
+ "TreeBlockModel",
157
161
  "KanbanBlockModel",
158
162
  "DetailsBlockModel",
159
163
  "ListBlockModel",
@@ -162,6 +166,7 @@ const FILTER_TARGET_BLOCK_USES = /* @__PURE__ */ new Set([
162
166
  "MapBlockModel",
163
167
  "CommentsBlockModel"
164
168
  ]);
169
+ const TREE_CONNECT_TARGET_BLOCK_USES = new Set(FILTER_TARGET_BLOCK_USES);
165
170
  const EDITABLE_FIELD_WRAPPER_USES = /* @__PURE__ */ new Set(["FormItemModel", "FilterFormItemModel", "PatternFormItemModel"]);
166
171
  const DISPLAY_FIELD_WRAPPER_USES = /* @__PURE__ */ new Set([
167
172
  "DetailsItemModel",
@@ -293,6 +298,7 @@ const POPUP_COLLECTION_BLOCK_SCENES = {
293
298
  CommentsBlockModel: ["one", "many"],
294
299
  TableBlockModel: ["many"],
295
300
  CalendarBlockModel: ["many"],
301
+ TreeBlockModel: ["filter"],
296
302
  KanbanBlockModel: ["many"],
297
303
  ListBlockModel: ["many"],
298
304
  GridCardBlockModel: ["many"],
@@ -951,8 +957,8 @@ class FlowSurfacesService {
951
957
  return this.patchResolvedNodeConfigureOptions(node, projected, enabledPackages);
952
958
  }
953
959
  patchResolvedNodeConfigureOptions(node, projected, enabledPackages) {
954
- var _a, _b, _c;
955
- if (!((_a = projected == null ? void 0 : projected.configureOptions) == null ? void 0 : _a.fieldComponent) || !(node == null ? void 0 : node.use)) {
960
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
961
+ if (!((_a = projected == null ? void 0 : projected.configureOptions) == null ? void 0 : _a.fieldType) || !(node == null ? void 0 : node.use)) {
956
962
  return projected;
957
963
  }
958
964
  try {
@@ -967,20 +973,107 @@ class FlowSurfacesService {
967
973
  if (!(supportedFieldUses == null ? void 0 : supportedFieldUses.size)) {
968
974
  return projected;
969
975
  }
976
+ const supportedFieldTypes = Array.from(supportedFieldUses).map((use) => (0, import_field_type_resolver.getPublicFieldTypeForUse)(use)).filter(Boolean);
970
977
  const configureOptions = import_lodash.default.cloneDeep(projected.configureOptions || {});
971
- configureOptions.fieldComponent = {
972
- type: ((_c = configureOptions.fieldComponent) == null ? void 0 : _c.type) || "string",
973
- ...configureOptions.fieldComponent || {},
974
- enum: Array.from(supportedFieldUses)
978
+ configureOptions.fieldType = {
979
+ type: ((_c = configureOptions.fieldType) == null ? void 0 : _c.type) || "string",
980
+ ...configureOptions.fieldType || {},
981
+ enum: Array.from(new Set(supportedFieldTypes))
975
982
  };
983
+ const innerField = ((_d = node == null ? void 0 : node.subModels) == null ? void 0 : _d.field) || node;
984
+ const relationFieldTypes = Array.from(new Set(supportedFieldTypes));
985
+ const defaultTitleField = this.getAssociationDefaultTitleFieldName(
986
+ fieldSource.field,
987
+ (_e = fieldSource.fieldSettingsInit) == null ? void 0 : _e.dataSourceKey
988
+ );
976
989
  return {
977
990
  ...projected,
978
- configureOptions
991
+ configureOptions,
992
+ relation: {
993
+ ...projected.relation,
994
+ fieldTypes: relationFieldTypes,
995
+ current: (0, import_service_utils.buildDefinedPayload)({
996
+ fieldType: (0, import_field_type_resolver.getPublicFieldTypeForUse)(((_g = (_f = innerField == null ? void 0 : innerField.stepParams) == null ? void 0 : _f.fieldBinding) == null ? void 0 : _g.use) || (innerField == null ? void 0 : innerField.use)),
997
+ fields: this.collectRelationNestedFieldPaths(innerField),
998
+ selectorFields: this.collectRelationSelectorFieldPaths(innerField),
999
+ titleField: ((_h = innerField == null ? void 0 : innerField.props) == null ? void 0 : _h.titleField) || ((_i = node == null ? void 0 : node.props) == null ? void 0 : _i.titleField)
1000
+ }),
1001
+ defaults: (0, import_service_utils.buildDefinedPayload)({
1002
+ titleField: defaultTitleField
1003
+ }),
1004
+ candidates: this.buildRelationFieldTypeCandidates(relationFieldTypes, defaultTitleField),
1005
+ configureOptions
1006
+ }
979
1007
  };
980
1008
  } catch {
981
1009
  return projected;
982
1010
  }
983
1011
  }
1012
+ buildRelationFieldTypeCandidates(fieldTypes, defaultTitleField) {
1013
+ return fieldTypes.map((fieldType) => {
1014
+ const defaults = {
1015
+ titleField: defaultTitleField
1016
+ };
1017
+ if (["subForm", "subFormList", "subDetails", "subDetailsList", "subTable", "popupSubTable"].includes(fieldType) && defaultTitleField) {
1018
+ defaults.fields = [defaultTitleField];
1019
+ }
1020
+ if (fieldType === "picker" && defaultTitleField) {
1021
+ defaults.selectorFields = [defaultTitleField];
1022
+ }
1023
+ return {
1024
+ fieldType,
1025
+ defaults: (0, import_service_utils.buildDefinedPayload)(defaults)
1026
+ };
1027
+ });
1028
+ }
1029
+ collectRelationNestedFieldPaths(fieldNode) {
1030
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
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
+ };
1041
+ if (["SubTableFieldModel", "DisplaySubTableFieldModel"].includes(fieldUse)) {
1042
+ return import_lodash.default.castArray(((_e = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _e.columns) || []).map((item) => {
1043
+ var _a2, _b2, _c2;
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;
1045
+ }).map(toPublicFieldPath).filter(Boolean);
1046
+ }
1047
+ if (fieldUse === "PopupSubTableFieldModel") {
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) => {
1049
+ var _a2, _b2, _c2;
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;
1051
+ }).map(toPublicFieldPath).filter(Boolean);
1052
+ }
1053
+ if (["SubFormFieldModel", "SubFormListFieldModel", "DisplaySubItemFieldModel", "DisplaySubListFieldModel"].includes(
1054
+ fieldUse
1055
+ )) {
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) => {
1057
+ var _a2, _b2, _c2;
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;
1059
+ }).map(toPublicFieldPath).filter(Boolean);
1060
+ }
1061
+ return void 0;
1062
+ }
1063
+ collectRelationSelectorFieldPaths(fieldNode) {
1064
+ var _a, _b, _c, _d, _e, _f;
1065
+ 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();
1066
+ if (fieldUse !== "RecordPickerFieldModel") {
1067
+ return void 0;
1068
+ }
1069
+ const table = import_lodash.default.castArray(((_e = (_d = (_c = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _c["grid-block"]) == null ? void 0 : _d.subModels) == null ? void 0 : _e.items) || []).find(
1070
+ (item) => (item == null ? void 0 : item.use) === "TableBlockModel"
1071
+ );
1072
+ return import_lodash.default.castArray(((_f = table == null ? void 0 : table.subModels) == null ? void 0 : _f.columns) || []).map((item) => {
1073
+ var _a2, _b2, _c2;
1074
+ 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;
1075
+ }).filter(Boolean);
1076
+ }
984
1077
  projectCatalogItem(item, expand) {
985
1078
  return (0, import_catalog_smart.projectCatalogItem)(item, expand, {
986
1079
  getEditableDomains: this.getEditableDomains.bind(this),
@@ -3738,6 +3831,7 @@ class FlowSurfacesService {
3738
3831
  }
3739
3832
  await this.applyInlineNodeSettings(actionName, targetUid, settings, options);
3740
3833
  },
3834
+ resolveBlockSettings: (settings, state) => this.resolveComposeBlockSettings(settings, state.keyMap),
3741
3835
  createField: async (payload) => this.addField(payload, {
3742
3836
  ...options,
3743
3837
  popupTemplateAliasSession
@@ -3814,6 +3908,9 @@ class FlowSurfacesService {
3814
3908
  if ((current == null ? void 0 : current.use) === "CalendarBlockModel") {
3815
3909
  return this.configureCalendarBlock(target, current, values.changes, options);
3816
3910
  }
3911
+ if ((current == null ? void 0 : current.use) === "TreeBlockModel") {
3912
+ return this.configureTreeBlock(target, current, values.changes, options);
3913
+ }
3817
3914
  if ((current == null ? void 0 : current.use) === "KanbanBlockModel") {
3818
3915
  return this.configureKanbanBlock(target, current, values.changes, options);
3819
3916
  }
@@ -3872,7 +3969,10 @@ class FlowSurfacesService {
3872
3969
  return this.configureFieldNode(target, values.changes, options);
3873
3970
  }
3874
3971
  if (import_node_use_sets.ACTION_BUTTON_USES.has((current == null ? void 0 : current.use) || "")) {
3875
- return this.configureActionNode(target, current.use, values.changes, options);
3972
+ return this.configureActionNode(target, current.use, values.changes, {
3973
+ ...options,
3974
+ current
3975
+ });
3876
3976
  }
3877
3977
  (0, import_errors.throwBadRequest)(`flowSurfaces configure does not support configureOptions on '${(current == null ? void 0 : current.use) || resolved.uid}'`);
3878
3978
  }
@@ -4808,7 +4908,7 @@ class FlowSurfacesService {
4808
4908
  };
4809
4909
  }
4810
4910
  async addBlock(values, options = {}) {
4811
- var _a, _b, _c, _d, _e;
4911
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4812
4912
  const templateRef = import_lodash.default.isUndefined(values == null ? void 0 : values.template) ? void 0 : this.normalizeFlowTemplateReference("addBlock", values.template, {
4813
4913
  allowUsage: true,
4814
4914
  expectedType: "block"
@@ -4838,6 +4938,7 @@ class FlowSurfacesService {
4838
4938
  (0, import_errors.throwBadRequest)("flowSurfaces addBlock does not allow resource and resourceInit at the same time");
4839
4939
  }
4840
4940
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
4941
+ const hasInlineFields = Object.prototype.hasOwnProperty.call(values || {}, "fields") || Object.prototype.hasOwnProperty.call(values || {}, "fieldsLayout");
4841
4942
  let resolvedTarget = await this.locator.resolve(target, options);
4842
4943
  let targetNode = await this.loadResolvedNode(resolvedTarget, options.transaction);
4843
4944
  const targetOpenView = this.resolvePopupHostOpenView(targetNode);
@@ -4872,6 +4973,16 @@ class FlowSurfacesService {
4872
4973
  requireCreateSupported: true
4873
4974
  }
4874
4975
  );
4976
+ const inlineFields = hasInlineFields ? this.normalizeComposeBlock(
4977
+ {
4978
+ key: String((values == null ? void 0 : values.key) || catalogItem.key || (values == null ? void 0 : values.type) || (values == null ? void 0 : values.use) || "addBlock_inline").trim() || "addBlock_inline",
4979
+ type: catalogItem.key || values.type,
4980
+ fields: values.fields,
4981
+ fieldsLayout: values.fieldsLayout
4982
+ },
4983
+ 0,
4984
+ enabledPackages
4985
+ ) : null;
4875
4986
  const resolvedResourceInit = await this.resolvePopupCollectionBlockResourceInit({
4876
4987
  actionName: "addBlock",
4877
4988
  blockUse: catalogItem.use,
@@ -4945,6 +5056,73 @@ class FlowSurfacesService {
4945
5056
  } : {}
4946
5057
  };
4947
5058
  await this.applyInlineNodeSettings("addBlock", created, inlineSettings, options);
5059
+ if ((_f = inlineFields == null ? void 0 : inlineFields.fields) == null ? void 0 : _f.length) {
5060
+ const fieldTargetUid = this.resolveComposeFieldContainerUid(inlineFields, result);
5061
+ const createdByKey = {};
5062
+ for (const fieldSpec of inlineFields.fields) {
5063
+ const createdField = await this.addField(
5064
+ {
5065
+ target: {
5066
+ uid: fieldTargetUid
5067
+ },
5068
+ ...fieldSpec.key ? { key: fieldSpec.key } : {},
5069
+ ...fieldSpec.fieldPath ? { fieldPath: fieldSpec.fieldPath } : {},
5070
+ ...fieldSpec.associationPathName ? { associationPathName: fieldSpec.associationPathName } : {},
5071
+ ...fieldSpec.renderer ? { renderer: fieldSpec.renderer } : {},
5072
+ ...fieldSpec.type ? { type: fieldSpec.type } : {},
5073
+ ...fieldSpec.fieldType ? { fieldType: fieldSpec.fieldType } : {},
5074
+ ...!import_lodash.default.isUndefined(fieldSpec.fields) ? { fields: fieldSpec.fields } : {},
5075
+ ...!import_lodash.default.isUndefined(fieldSpec.selectorFields) ? { selectorFields: fieldSpec.selectorFields } : {},
5076
+ ...fieldSpec.titleField ? { titleField: fieldSpec.titleField } : {},
5077
+ ...fieldSpec.openMode ? { openMode: fieldSpec.openMode } : {},
5078
+ ...fieldSpec.popupSize ? { popupSize: fieldSpec.popupSize } : {},
5079
+ ...!import_lodash.default.isUndefined(fieldSpec.pageSize) ? { pageSize: fieldSpec.pageSize } : {},
5080
+ ...!import_lodash.default.isUndefined(fieldSpec.showIndex) ? { showIndex: fieldSpec.showIndex } : {},
5081
+ ...fieldSpec.popup ? { popup: fieldSpec.popup } : {},
5082
+ ...fieldSpec.__autoPopupForRelationField ? { __autoPopupForRelationField: true } : {},
5083
+ ...fieldSpec[import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY] ? {
5084
+ [import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY]: fieldSpec[import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY]
5085
+ } : {}
5086
+ },
5087
+ {
5088
+ transaction: options.transaction,
5089
+ enabledPackages
5090
+ }
5091
+ );
5092
+ if (fieldSpec.settings && Object.keys(fieldSpec.settings).length) {
5093
+ await this.applyInlineFieldSettings("addBlock field", createdField, fieldSpec.settings, {
5094
+ transaction: options.transaction
5095
+ });
5096
+ }
5097
+ const layoutUid = createdField.wrapperUid || createdField.uid;
5098
+ if (layoutUid && fieldSpec.key) {
5099
+ createdByKey[fieldSpec.key] = { uid: layoutUid };
5100
+ }
5101
+ }
5102
+ if (inlineFields.fieldsLayout && Object.keys(createdByKey).length) {
5103
+ const layoutHost = await this.repository.findModelById(created, {
5104
+ transaction: options.transaction,
5105
+ includeAsyncNode: true
5106
+ });
5107
+ const layoutItems = import_lodash.default.castArray(
5108
+ ((_i = (_h = (_g = layoutHost == null ? void 0 : layoutHost.subModels) == null ? void 0 : _g.grid) == null ? void 0 : _h.subModels) == null ? void 0 : _i.items) || ((_j = layoutHost == null ? void 0 : layoutHost.subModels) == null ? void 0 : _j.items) || []
5109
+ );
5110
+ const layoutPayload = this.buildComposeLayoutPayload({
5111
+ layout: inlineFields.fieldsLayout,
5112
+ createdByKey,
5113
+ finalItems: layoutItems
5114
+ });
5115
+ await this.setLayout(
5116
+ {
5117
+ target: {
5118
+ uid: created
5119
+ },
5120
+ ...layoutPayload
5121
+ },
5122
+ options
5123
+ );
5124
+ }
5125
+ }
4948
5126
  if (!options.skipDefaultBlockActions) {
4949
5127
  await this.applyDefaultActionsForCreatedBlock(
4950
5128
  {
@@ -4991,6 +5169,8 @@ class FlowSurfacesService {
4991
5169
  return result2;
4992
5170
  }
4993
5171
  const target = await this.prepareWriteTarget("addField", values == null ? void 0 : values.target, values, options);
5172
+ (0, import_field_type_resolver.assertNoInternalFieldKeys)(values, "flowSurfaces addField");
5173
+ (0, import_field_type_resolver.assertNoInternalFieldKeys)(values == null ? void 0 : values.settings, "flowSurfaces addField.settings");
4994
5174
  (0, import_service_utils.ensureNoRawDirectAddKeys)("addField", values, [
4995
5175
  "wrapperProps",
4996
5176
  "fieldProps",
@@ -5007,6 +5187,8 @@ class FlowSurfacesService {
5007
5187
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
5008
5188
  const isFilterFormItem = container.wrapperUse === "FilterFormItemModel";
5009
5189
  const isApprovalFormTarget = (0, import_approval.isApprovalFormContainerUse)(container.ownerUse);
5190
+ const requestedLegacyFieldUse = (0, import_service_utils.resolveRequestedFieldUseAlias)(values);
5191
+ let requestedFieldUse = (0, import_service_utils.resolveRequestedFieldUse)(values);
5010
5192
  const requestedStandaloneType = typeof values.type === "string" && values.type.trim().length ? values.type.trim() : void 0;
5011
5193
  const fieldCapability = (0, import_catalog.resolveSupportedFieldCapability)({
5012
5194
  containerUse: container.ownerUse,
@@ -5017,6 +5199,9 @@ class FlowSurfacesService {
5017
5199
  enabledPackages
5018
5200
  });
5019
5201
  if (fieldCapability.standaloneUse) {
5202
+ if ((0, import_service_utils.hasOwnDefined)(values, "fieldType")) {
5203
+ (0, import_errors.throwBadRequest)("flowSurfaces fieldType is only supported for relation fields");
5204
+ }
5020
5205
  if (inlinePopup) {
5021
5206
  (0, import_errors.throwBadRequest)(`flowSurfaces addField type '${values.type}' does not support popup`);
5022
5207
  }
@@ -5122,6 +5307,32 @@ class FlowSurfacesService {
5122
5307
  associationPathName: resolvedField.associationPathName,
5123
5308
  field: resolvedField.field
5124
5309
  });
5310
+ const relationFieldTypeResolution = (0, import_field_type_resolver.resolveRelationFieldType)({
5311
+ fieldType: values.fieldType,
5312
+ containerUse: container.ownerUse,
5313
+ field: resolvedField.field,
5314
+ dataSourceKey: resolvedField.dataSourceKey,
5315
+ getCollection: (dataSourceKey, collectionName) => this.getCollection(dataSourceKey, collectionName),
5316
+ fields: values.fields,
5317
+ selectorFields: values.selectorFields,
5318
+ titleField: values.titleField,
5319
+ openMode: values.openMode,
5320
+ popupSize: values.popupSize,
5321
+ pageSize: values.pageSize,
5322
+ showIndex: values.showIndex,
5323
+ context: "addField"
5324
+ });
5325
+ if (relationFieldTypeResolution) {
5326
+ if (values.renderer) {
5327
+ (0, import_errors.throwBadRequest)(`flowSurfaces addField fieldType cannot be combined with renderer`);
5328
+ }
5329
+ if (requestedLegacyFieldUse && requestedLegacyFieldUse !== relationFieldTypeResolution.fieldUse) {
5330
+ (0, import_errors.throwBadRequest)(
5331
+ `flowSurfaces fieldUse '${requestedLegacyFieldUse}' does not match fieldType '${relationFieldTypeResolution.fieldType}'`
5332
+ );
5333
+ }
5334
+ requestedFieldUse = relationFieldTypeResolution.fieldUse;
5335
+ }
5125
5336
  const filterFormInit = isFilterFormItem ? {
5126
5337
  filterField: (0, import_service_helpers.buildFilterFieldMeta)(resolvedField.field),
5127
5338
  ...(selectedFilterTarget == null ? void 0 : selectedFilterTarget.ownerUid) ? { defaultTargetUid: selectedFilterTarget.ownerUid } : {}
@@ -5129,25 +5340,29 @@ class FlowSurfacesService {
5129
5340
  let capabilityField = preferredCapabilityField;
5130
5341
  let boundFieldCapability;
5131
5342
  if ((fieldMenuCandidate == null ? void 0 : fieldMenuCandidate.explicitWrapperUse) && (fieldMenuCandidate == null ? void 0 : fieldMenuCandidate.explicitFieldUse) && !values.renderer) {
5132
- if ((0, import_service_utils.hasOwnDefined)(values, "fieldUse") && values.fieldUse !== fieldMenuCandidate.explicitFieldUse) {
5343
+ if (requestedLegacyFieldUse && requestedLegacyFieldUse !== fieldMenuCandidate.explicitFieldUse) {
5133
5344
  (0, import_errors.throwBadRequest)(
5134
- `flowSurfaces fieldUse '${values.fieldUse}' does not match inferred fieldUse '${fieldMenuCandidate.explicitFieldUse}' under '${container.ownerUse}'`
5345
+ `flowSurfaces fieldUse '${requestedLegacyFieldUse}' does not match inferred fieldUse '${fieldMenuCandidate.explicitFieldUse}' under '${container.ownerUse}'`
5135
5346
  );
5136
5347
  }
5137
- boundFieldCapability = {
5138
- wrapperUse: fieldMenuCandidate.explicitWrapperUse,
5139
- fieldUse: fieldMenuCandidate.explicitFieldUse,
5140
- inferredFieldUse: fieldMenuCandidate.explicitFieldUse,
5141
- standaloneUse: void 0,
5142
- renderer: void 0
5143
- };
5144
- capabilityField = resolvedField.field;
5145
- } else {
5348
+ if (!relationFieldTypeResolution) {
5349
+ boundFieldCapability = {
5350
+ wrapperUse: fieldMenuCandidate.explicitWrapperUse,
5351
+ fieldUse: fieldMenuCandidate.explicitFieldUse,
5352
+ inferredFieldUse: fieldMenuCandidate.explicitFieldUse,
5353
+ standaloneUse: void 0,
5354
+ renderer: void 0
5355
+ };
5356
+ capabilityField = resolvedField.field;
5357
+ }
5358
+ }
5359
+ if (!boundFieldCapability) {
5146
5360
  try {
5147
5361
  boundFieldCapability = (0, import_catalog.resolveSupportedFieldCapability)({
5148
5362
  containerUse: container.ownerUse,
5149
5363
  field: capabilityField,
5150
- requestedFieldUse: values.fieldUse,
5364
+ requestedFieldUse,
5365
+ requestedFieldUseMode: relationFieldTypeResolution ? "fieldType" : "fieldUse",
5151
5366
  requestedWrapperUse: container.wrapperUse,
5152
5367
  requestedRenderer: values.renderer,
5153
5368
  enabledPackages,
@@ -5155,12 +5370,13 @@ class FlowSurfacesService {
5155
5370
  getCollection: (dataSourceKey, collectionName) => this.getCollection(dataSourceKey, collectionName)
5156
5371
  });
5157
5372
  } catch (error) {
5158
- if ((0, import_service_utils.hasOwnDefined)(values, "fieldUse") && capabilityField !== resolvedField.field && error instanceof import_errors.FlowSurfaceBadRequestError) {
5373
+ if (requestedFieldUse && capabilityField !== resolvedField.field && error instanceof import_errors.FlowSurfaceBadRequestError) {
5159
5374
  capabilityField = resolvedField.field;
5160
5375
  boundFieldCapability = (0, import_catalog.resolveSupportedFieldCapability)({
5161
5376
  containerUse: container.ownerUse,
5162
5377
  field: capabilityField,
5163
- requestedFieldUse: values.fieldUse,
5378
+ requestedFieldUse,
5379
+ requestedFieldUseMode: relationFieldTypeResolution ? "fieldType" : "fieldUse",
5164
5380
  requestedWrapperUse: container.wrapperUse,
5165
5381
  requestedRenderer: values.renderer,
5166
5382
  enabledPackages,
@@ -5194,9 +5410,17 @@ class FlowSurfacesService {
5194
5410
  boundFieldCapability.fieldUse,
5195
5411
  capabilityField
5196
5412
  );
5197
- const defaultTitleField = titleFieldSyncDecision.titleField ?? normalizedFieldBinding.defaultTitleField ?? (fieldMenuCandidate == null ? void 0 : fieldMenuCandidate.defaultTitleField);
5413
+ const defaultTitleField = (relationFieldTypeResolution == null ? void 0 : relationFieldTypeResolution.titleField) ?? titleFieldSyncDecision.titleField ?? normalizedFieldBinding.defaultTitleField ?? (fieldMenuCandidate == null ? void 0 : fieldMenuCandidate.defaultTitleField);
5198
5414
  const wrapperShouldPersistTitleField = !import_lodash.default.isUndefined(defaultTitleField) && TITLE_FIELD_SUPPORTED_WRAPPER_USES.has(boundFieldCapability.wrapperUse || "");
5199
- const fieldShouldPersistTitleField = !import_lodash.default.isUndefined(defaultTitleField);
5415
+ const fieldShouldPersistTitleField = !import_lodash.default.isUndefined(defaultTitleField) && this.supportsFieldTitleFieldProp(boundFieldCapability.fieldUse);
5416
+ const normalizedDefaultFieldProps = this.normalizeFieldPropsForUse(
5417
+ boundFieldCapability.fieldUse,
5418
+ defaultFieldState.fieldProps || {}
5419
+ );
5420
+ const normalizedInlineFieldProps = this.normalizeFieldPropsForUse(
5421
+ boundFieldCapability.fieldUse,
5422
+ values.fieldProps || {}
5423
+ );
5200
5424
  const tree = (0, import_builder.buildFieldTree)({
5201
5425
  wrapperUse: boundFieldCapability.wrapperUse,
5202
5426
  fieldUse: boundFieldCapability.fieldUse,
@@ -5213,9 +5437,9 @@ class FlowSurfacesService {
5213
5437
  ),
5214
5438
  fieldProps: import_lodash.default.merge(
5215
5439
  {},
5216
- defaultFieldState.fieldProps || {},
5440
+ normalizedDefaultFieldProps,
5217
5441
  fieldShouldPersistTitleField ? { titleField: defaultTitleField } : {},
5218
- values.fieldProps || {}
5442
+ normalizedInlineFieldProps
5219
5443
  )
5220
5444
  });
5221
5445
  this.contractGuard.validateNodeTreeAgainstContract(tree.model);
@@ -5254,6 +5478,22 @@ class FlowSurfacesService {
5254
5478
  associationPathName: normalizedFieldBinding.associationPathName,
5255
5479
  fieldPath: normalizedFieldBinding.fieldPath
5256
5480
  };
5481
+ if (relationFieldTypeResolution) {
5482
+ await this.applyResolvedRelationFieldType({
5483
+ fieldUid: tree.innerUid,
5484
+ fieldUse: boundFieldCapability.fieldUse,
5485
+ targetCollection: relationFieldTypeResolution.targetCollection,
5486
+ relationFieldInit: normalizedFieldBinding,
5487
+ fields: relationFieldTypeResolution.fields,
5488
+ selectorFields: relationFieldTypeResolution.selectorFields,
5489
+ titleField: relationFieldTypeResolution.titleField,
5490
+ openMode: relationFieldTypeResolution.openMode,
5491
+ popupSize: relationFieldTypeResolution.popupSize,
5492
+ pageSize: relationFieldTypeResolution.pageSize,
5493
+ showIndex: relationFieldTypeResolution.showIndex,
5494
+ transaction: options.transaction
5495
+ });
5496
+ }
5257
5497
  await this.applyInlineFieldSettings("addField", result, inlineSettings, options);
5258
5498
  await this.applyInlineFieldPopup("addField", result, inlinePopup, {
5259
5499
  ...options,
@@ -6555,6 +6795,27 @@ class FlowSurfacesService {
6555
6795
  (0, import_service_utils.rethrowInlineConfigurationError)(error, `flowSurfaces ${actionName} settings invalid`);
6556
6796
  }
6557
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
+ }
6558
6819
  async applyInlineFieldPopup(actionName, result, popup, options) {
6559
6820
  popup = this.prepareInlinePopupTemplateAliases(actionName, popup, options.popupTemplateAliasSession);
6560
6821
  const fieldHostUid = result.fieldUid || result.uid;
@@ -7602,6 +7863,9 @@ class FlowSurfacesService {
7602
7863
  if (typeof normalizedValues[domain] === "undefined") {
7603
7864
  return;
7604
7865
  }
7866
+ if (domain === "flowRegistry") {
7867
+ this.assertNoTreeConnectFieldsFlowRegistry(current, normalizedValues[domain], "updateSettings");
7868
+ }
7605
7869
  if (!contract.editableDomains.includes(domain)) {
7606
7870
  (0, import_errors.throwBadRequest)(`flowSurfaces updateSettings domain '${domain}' is not editable`);
7607
7871
  }
@@ -7633,7 +7897,6 @@ class FlowSurfacesService {
7633
7897
  this.syncChartConfigureForUpdateSettings(current, nextPayload);
7634
7898
  await this.validateChartConfigureForUpdateSettings(current, nextPayload, options.transaction);
7635
7899
  this.syncCanonicalBlockHeaderForUpdateSettings(current, nextPayload);
7636
- this.syncMapHeightChromeForUpdateSettings(current, nextPayload);
7637
7900
  this.syncChartCardRuntimeStepParamsForUpdateSettings(
7638
7901
  current,
7639
7902
  nextPayload,
@@ -7824,6 +8087,7 @@ class FlowSurfacesService {
7824
8087
  import_lodash.default.set(values, titleDescriptionPath, normalizedTitleDescription);
7825
8088
  }
7826
8089
  syncCanonicalBlockHeaderForUpdateSettings(current, nextPayload) {
8090
+ var _a;
7827
8091
  const semanticUse = (0, import_approval.normalizeApprovalSemanticUse)(current == null ? void 0 : current.use);
7828
8092
  if (!CANONICAL_BLOCK_HEADER_USES.has(semanticUse)) {
7829
8093
  return;
@@ -7834,11 +8098,19 @@ class FlowSurfacesService {
7834
8098
  const nextStepParams = import_lodash.default.cloneDeep(nextPayload.stepParams ?? (current == null ? void 0 : current.stepParams) ?? {});
7835
8099
  const nextCardSettings = import_lodash.default.cloneDeep(import_lodash.default.get(nextStepParams, ["cardSettings"]) || {});
7836
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;
7837
8104
  if (normalizedTitleDescription) {
7838
8105
  import_lodash.default.set(nextCardSettings, ["titleDescription"], normalizedTitleDescription);
7839
8106
  } else {
7840
8107
  import_lodash.default.unset(nextCardSettings, ["titleDescription"]);
7841
8108
  }
8109
+ if (normalizedBlockHeight) {
8110
+ import_lodash.default.set(nextCardSettings, ["blockHeight"], normalizedBlockHeight);
8111
+ } else {
8112
+ import_lodash.default.unset(nextCardSettings, ["blockHeight"]);
8113
+ }
7842
8114
  if (import_lodash.default.isEmpty(nextCardSettings)) {
7843
8115
  import_lodash.default.unset(nextStepParams, ["cardSettings"]);
7844
8116
  } else {
@@ -7872,28 +8144,6 @@ class FlowSurfacesService {
7872
8144
  );
7873
8145
  }
7874
8146
  }
7875
- syncMapHeightChromeForUpdateSettings(current, nextPayload) {
7876
- if ((current == null ? void 0 : current.use) !== "MapBlockModel") {
7877
- return;
7878
- }
7879
- const nextProps = import_lodash.default.isPlainObject(nextPayload.props) ? nextPayload.props : void 0;
7880
- if (!nextProps) {
7881
- return;
7882
- }
7883
- const nextDecoratorProps = import_lodash.default.cloneDeep(nextPayload.decoratorProps ?? (current == null ? void 0 : current.decoratorProps) ?? {});
7884
- let changed = false;
7885
- if (Object.prototype.hasOwnProperty.call(nextProps, "height") && nextDecoratorProps.height !== nextProps.height) {
7886
- nextDecoratorProps.height = nextProps.height;
7887
- changed = true;
7888
- }
7889
- if (Object.prototype.hasOwnProperty.call(nextProps, "heightMode") && nextDecoratorProps.heightMode !== nextProps.heightMode) {
7890
- nextDecoratorProps.heightMode = nextProps.heightMode;
7891
- changed = true;
7892
- }
7893
- if (changed) {
7894
- nextPayload.decoratorProps = (0, import_service_utils.buildDefinedPayload)(nextDecoratorProps);
7895
- }
7896
- }
7897
8147
  async normalizeOpenViewForUpdateSettings(actionName, current, nextPayload, options = {}) {
7898
8148
  const openViewPaths = [
7899
8149
  ["popupSettings", "openView"],
@@ -8161,6 +8411,7 @@ class FlowSurfacesService {
8161
8411
  (0, import_errors.throwBadRequest)(`flowSurfaces setEventFlows is not supported on '${(current == null ? void 0 : current.use) || target.uid}'`);
8162
8412
  }
8163
8413
  const flows = values.flowRegistry || values.flows || {};
8414
+ this.assertNoTreeConnectFieldsFlowRegistry(current, flows, "setEventFlows");
8164
8415
  this.contractGuard.validateFlowRegistry(current, flows);
8165
8416
  if (target.kind === "tab" && target.tabRoute) {
8166
8417
  await this.routeSync.persistTabSettings(
@@ -8276,10 +8527,13 @@ class FlowSurfacesService {
8276
8527
  });
8277
8528
  this.assertRemoveNodeResolvedTarget(resolved, node);
8278
8529
  if ((node == null ? void 0 : node.use) === "FilterFormItemModel") {
8279
- 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);
8280
8534
  }
8281
8535
  if (FILTER_TARGET_BLOCK_USES.has((node == null ? void 0 : node.use) || "")) {
8282
- await this.removeFilterFormTargetBindings(resolved.uid, options.transaction);
8536
+ await this.removeFilterTargetBindings(resolved.uid, options.transaction);
8283
8537
  }
8284
8538
  const approvalRoot = await this.findApprovalSurfaceRootForNode(resolved.uid, options.transaction);
8285
8539
  await this.removeNodeTreeWithBindings(resolved.uid, options.transaction);
@@ -9374,6 +9628,7 @@ class FlowSurfacesService {
9374
9628
  );
9375
9629
  const hasFields = Object.prototype.hasOwnProperty.call(input, "fields");
9376
9630
  const hasFieldGroups = Object.prototype.hasOwnProperty.call(input, "fieldGroups");
9631
+ const hasActions = Object.prototype.hasOwnProperty.call(input, "actions");
9377
9632
  const hasRecordActions = Object.prototype.hasOwnProperty.call(input, "recordActions");
9378
9633
  if (type === "calendar") {
9379
9634
  if (hasFields) {
@@ -9409,6 +9664,23 @@ class FlowSurfacesService {
9409
9664
  );
9410
9665
  }
9411
9666
  }
9667
+ if (type === "tree") {
9668
+ if (hasFields) {
9669
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support fields[]`);
9670
+ }
9671
+ if (hasFieldGroups) {
9672
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support fieldGroups[]`);
9673
+ }
9674
+ if (hasActions) {
9675
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support actions[]`);
9676
+ }
9677
+ if (hasRecordActions) {
9678
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support recordActions[]`);
9679
+ }
9680
+ if (Object.prototype.hasOwnProperty.call(input, "fieldsLayout")) {
9681
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support fieldsLayout`);
9682
+ }
9683
+ }
9412
9684
  if (hasFields && hasFieldGroups) {
9413
9685
  (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} cannot mix fields with fieldGroups`);
9414
9686
  }
@@ -9730,10 +10002,13 @@ class FlowSurfacesService {
9730
10002
  }
9731
10003
  }
9732
10004
  if (node.use === "FilterFormItemModel") {
9733
- 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);
9734
10009
  }
9735
10010
  if (FILTER_TARGET_BLOCK_USES.has(node.use || "")) {
9736
- await this.removeFilterFormTargetBindings(node.uid, transaction);
10011
+ await this.removeFilterTargetBindings(node.uid, transaction);
9737
10012
  }
9738
10013
  }
9739
10014
  async configurePage(target, changes, options) {
@@ -9801,15 +10076,11 @@ class FlowSurfacesService {
9801
10076
  }
9802
10077
  async configureTableBlock(target, changes, options) {
9803
10078
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("TableBlockModel");
9804
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10079
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
9805
10080
  (0, import_service_utils.assertSupportedSimpleChanges)("table", changes, allowedKeys);
9806
10081
  return this.updateSettings(
9807
10082
  {
9808
10083
  target,
9809
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
9810
- height: changes.height,
9811
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
9812
- }),
9813
10084
  stepParams: {
9814
10085
  ...cardSettings ? { cardSettings } : {},
9815
10086
  ...changes.resource ? {
@@ -9850,7 +10121,7 @@ class FlowSurfacesService {
9850
10121
  async configureCalendarBlock(target, current, changes, options) {
9851
10122
  var _a;
9852
10123
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("CalendarBlockModel");
9853
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10124
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
9854
10125
  (0, import_service_utils.assertSupportedSimpleChanges)("calendar", changes, allowedKeys);
9855
10126
  this.validateCalendarSettingValues("configure", {
9856
10127
  defaultView: changes.defaultView,
@@ -9903,10 +10174,6 @@ class FlowSurfacesService {
9903
10174
  quickCreatePopupSettings,
9904
10175
  eventPopupSettings
9905
10176
  }),
9906
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
9907
- height: changes.height,
9908
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
9909
- }),
9910
10177
  stepParams: {
9911
10178
  ...cardSettings ? { cardSettings } : {},
9912
10179
  ...changes.resource ? {
@@ -9950,10 +10217,93 @@ class FlowSurfacesService {
9950
10217
  await this.ensureCalendarBlockPopupHosts(reloaded, options.transaction);
9951
10218
  return result;
9952
10219
  }
10220
+ async configureTreeBlock(target, current, changes, options) {
10221
+ var _a, _b;
10222
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("TreeBlockModel");
10223
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10224
+ (0, import_service_utils.assertSupportedSimpleChanges)("tree", changes, allowedKeys);
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) || {});
10226
+ if ((0, import_service_utils.hasOwnDefined)(changes, "titleField")) {
10227
+ nextFieldNames.title = String(changes.titleField || "").trim();
10228
+ }
10229
+ const hasFieldNamesPatch = (0, import_service_utils.hasOwnDefined)(changes, "titleField") || import_lodash.default.isPlainObject(changes.fieldNames);
10230
+ const result = await this.updateSettings(
10231
+ {
10232
+ target,
10233
+ props: (0, import_service_utils.buildDefinedPayload)({
10234
+ ...(0, import_service_utils.hasOwnDefined)(changes, "searchable") ? { searchable: changes.searchable !== false } : {},
10235
+ ...(0, import_service_utils.hasOwnDefined)(changes, "defaultExpandAll") ? { defaultExpandAll: changes.defaultExpandAll === true } : {},
10236
+ ...(0, import_service_utils.hasOwnDefined)(changes, "includeDescendants") ? { includeDescendants: changes.includeDescendants !== false } : {},
10237
+ ...hasFieldNamesPatch ? { fieldNames: nextFieldNames } : {},
10238
+ ...(0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? { pageSize: changes.pageSize } : {}
10239
+ }),
10240
+ stepParams: {
10241
+ ...cardSettings ? { cardSettings } : {},
10242
+ ...changes.resource ? {
10243
+ resourceSettings: {
10244
+ init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
10245
+ }
10246
+ } : {},
10247
+ ...(0, import_service_utils.hasDefinedValue)(changes, [
10248
+ "searchable",
10249
+ "defaultExpandAll",
10250
+ "includeDescendants",
10251
+ "titleField",
10252
+ "pageSize",
10253
+ "dataScope",
10254
+ "sorting"
10255
+ ]) ? {
10256
+ treeSettings: (0, import_service_utils.buildDefinedPayload)({
10257
+ ...(0, import_service_utils.hasOwnDefined)(changes, "searchable") ? { searchable: { searchable: changes.searchable !== false } } : {},
10258
+ ...(0, import_service_utils.hasOwnDefined)(changes, "defaultExpandAll") ? { defaultExpandAll: { defaultExpandAll: changes.defaultExpandAll === true } } : {},
10259
+ ...(0, import_service_utils.hasOwnDefined)(changes, "includeDescendants") ? { includeDescendants: { includeDescendants: changes.includeDescendants !== false } } : {},
10260
+ ...(0, import_service_utils.hasOwnDefined)(changes, "titleField") ? { titleField: { titleField: nextFieldNames.title } } : {},
10261
+ ...(0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? { pageSize: { pageSize: changes.pageSize } } : {},
10262
+ ...(0, import_service_utils.hasOwnDefined)(changes, "dataScope") ? { dataScope: { filter: changes.dataScope } } : {},
10263
+ ...(0, import_service_utils.hasOwnDefined)(changes, "sorting") ? { defaultSorting: { sort: changes.sorting } } : {}
10264
+ })
10265
+ } : {}
10266
+ }
10267
+ },
10268
+ options
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;
10302
+ }
9953
10303
  async configureKanbanBlock(target, current, changes, options) {
9954
10304
  var _a;
9955
10305
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("KanbanBlockModel");
9956
- const blockCardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10306
+ const blockCardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
9957
10307
  (0, import_service_utils.assertSupportedSimpleChanges)("kanban", changes, allowedKeys);
9958
10308
  if (!import_lodash.default.isUndefined(changes.dragEnabled) && !import_lodash.default.isBoolean(changes.dragEnabled)) {
9959
10309
  (0, import_errors.throwBadRequest)("flowSurfaces configure kanban dragEnabled must be a boolean");
@@ -10232,15 +10582,11 @@ class FlowSurfacesService {
10232
10582
  } : {}
10233
10583
  });
10234
10584
  const updated = /* @__PURE__ */ new Set();
10235
- 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) {
10236
10586
  const blockResult = await this.updateSettings(
10237
10587
  {
10238
10588
  target,
10239
10589
  props: blockProps,
10240
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10241
- height: changes.height,
10242
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10243
- }),
10244
10590
  stepParams: blockStepParams
10245
10591
  },
10246
10592
  options
@@ -10417,16 +10763,12 @@ class FlowSurfacesService {
10417
10763
  }
10418
10764
  async configureListBlock(target, changes, options) {
10419
10765
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("ListBlockModel");
10420
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10766
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10421
10767
  (0, import_service_utils.assertSupportedSimpleChanges)("list", changes, allowedKeys);
10422
10768
  const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
10423
10769
  return this.updateSettings(
10424
10770
  {
10425
10771
  target,
10426
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10427
- height: changes.height,
10428
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10429
- }),
10430
10772
  stepParams: {
10431
10773
  ...cardSettings ? { cardSettings } : {},
10432
10774
  ...changes.resource ? {
@@ -10449,17 +10791,13 @@ class FlowSurfacesService {
10449
10791
  }
10450
10792
  async configureGridCardBlock(target, changes, options) {
10451
10793
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("GridCardBlockModel");
10452
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10794
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10453
10795
  (0, import_service_utils.assertSupportedSimpleChanges)("gridCard", changes, allowedKeys);
10454
10796
  const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
10455
10797
  const columns = (0, import_service_utils.normalizeGridCardColumns)(changes.columns);
10456
10798
  return this.updateSettings(
10457
10799
  {
10458
10800
  target,
10459
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10460
- height: changes.height,
10461
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10462
- }),
10463
10801
  stepParams: {
10464
10802
  ...cardSettings ? { cardSettings } : {},
10465
10803
  ...changes.resource ? {
@@ -10628,15 +10966,11 @@ class FlowSurfacesService {
10628
10966
  }
10629
10967
  async configureMapBlock(target, changes, options) {
10630
10968
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("MapBlockModel");
10631
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10969
+ const cardSettings = (0, import_service_utils.buildBlockCardSettingsFromSemanticChanges)(changes);
10632
10970
  (0, import_service_utils.assertSupportedSimpleChanges)("map", changes, allowedKeys);
10633
10971
  return this.updateSettings(
10634
10972
  {
10635
10973
  target,
10636
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10637
- height: changes.height,
10638
- heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10639
- }),
10640
10974
  stepParams: (0, import_service_utils.buildDefinedPayload)({
10641
10975
  ...cardSettings ? { cardSettings } : {},
10642
10976
  ...changes.resource ? {
@@ -10818,10 +11152,22 @@ class FlowSurfacesService {
10818
11152
  );
10819
11153
  }
10820
11154
  async configureFieldWrapper(target, current, changes, options) {
10821
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
11155
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
10822
11156
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
10823
11157
  (0, import_service_utils.assertSupportedSimpleChanges)("field wrapper", changes, (0, import_configure_options.getConfigureOptionKeysForUse)(current == null ? void 0 : current.use));
10824
- const rawWrapperChanges = import_lodash.default.omit(changes, ["clickToOpen", "openView", "code", "version", "fieldComponent"]);
11158
+ const rawWrapperChanges = import_lodash.default.omit(changes, [
11159
+ "clickToOpen",
11160
+ "openView",
11161
+ "code",
11162
+ "version",
11163
+ "fieldType",
11164
+ "fields",
11165
+ "selectorFields",
11166
+ "openMode",
11167
+ "popupSize",
11168
+ "pageSize",
11169
+ "showIndex"
11170
+ ]);
10825
11171
  const wrapperChanges = (current == null ? void 0 : current.use) === "TableColumnModel" && !(0, import_service_utils.hasOwnDefined)(rawWrapperChanges, "title") && (0, import_service_utils.hasOwnDefined)(rawWrapperChanges, "label") ? {
10826
11172
  ...rawWrapperChanges,
10827
11173
  title: rawWrapperChanges.label
@@ -10855,6 +11201,8 @@ class FlowSurfacesService {
10855
11201
  });
10856
11202
  const shouldSyncTitleField = titleFieldSyncDecision.shouldSync;
10857
11203
  const syncedTitleField = titleFieldSyncDecision.titleField;
11204
+ const shouldPatchTableColumnTitle = (current == null ? void 0 : current.use) === "TableColumnModel" && (0, import_service_utils.hasOwnDefined)(wrapperChanges, "title");
11205
+ const shouldPatchFieldSettings = (0, import_service_utils.hasDefinedValue)(wrapperChanges, ["fieldPath", "associationPathName"]) || shouldPatchTableColumnTitle;
10858
11206
  if (Object.keys(wrapperChanges).length) {
10859
11207
  await this.updateSettings(
10860
11208
  {
@@ -10889,8 +11237,8 @@ class FlowSurfacesService {
10889
11237
  labelWidth: wrapperChanges.labelWidth,
10890
11238
  labelWrap: wrapperChanges.labelWrap
10891
11239
  }),
10892
- stepParams: (0, import_service_utils.hasDefinedValue)(wrapperChanges, ["fieldPath", "associationPathName"]) || (current == null ? void 0 : current.use) === "TableColumnModel" && (0, import_service_utils.hasOwnDefined)(wrapperChanges, "title") ? (0, import_service_utils.buildDefinedPayload)({
10893
- ...(current == null ? void 0 : current.use) === "TableColumnModel" && (0, import_service_utils.hasOwnDefined)(wrapperChanges, "title") ? {
11240
+ stepParams: shouldPatchFieldSettings ? (0, import_service_utils.buildDefinedPayload)({
11241
+ ...shouldPatchTableColumnTitle ? {
10894
11242
  tableColumnSettings: {
10895
11243
  title: {
10896
11244
  title: wrapperChanges.title
@@ -10926,24 +11274,70 @@ class FlowSurfacesService {
10926
11274
  );
10927
11275
  }
10928
11276
  }
10929
- if ((0, import_service_utils.hasOwnDefined)(changes, "fieldComponent")) {
11277
+ let effectiveInnerFieldUse = innerField == null ? void 0 : innerField.use;
11278
+ let fieldTypeResolution;
11279
+ let relationTitleFieldToApply;
11280
+ if ((0, import_service_utils.hasOwnDefined)(changes, "fieldType") || (0, import_service_utils.hasOwnDefined)(changes, "fields") || (0, import_service_utils.hasOwnDefined)(changes, "selectorFields") || (0, import_service_utils.hasOwnDefined)(changes, "titleField") || (0, import_service_utils.hasOwnDefined)(changes, "openMode") || (0, import_service_utils.hasOwnDefined)(changes, "popupSize") || (0, import_service_utils.hasOwnDefined)(changes, "pageSize") || (0, import_service_utils.hasOwnDefined)(changes, "showIndex")) {
10930
11281
  if (!innerUid) {
10931
11282
  (0, import_errors.throwConflict)(
10932
11283
  `flowSurfaces configure field wrapper '${current == null ? void 0 : current.use}' cannot resolve inner field`,
10933
11284
  "FLOW_SURFACE_INNER_FIELD_MISSING"
10934
11285
  );
10935
11286
  }
11287
+ const fieldSource = this.resolveFieldComponentFieldSource(current, normalizedBinding);
11288
+ const currentPublicFieldType = (0, import_field_type_resolver.getPublicFieldTypeForUse)(
11289
+ ((_k = (_j = innerField == null ? void 0 : innerField.stepParams) == null ? void 0 : _j.fieldBinding) == null ? void 0 : _k.use) || (innerField == null ? void 0 : innerField.use)
11290
+ );
11291
+ const shouldApplyResolverDefaults = (0, import_service_utils.hasOwnDefined)(changes, "fieldType") && changes.fieldType !== currentPublicFieldType;
11292
+ fieldTypeResolution = (0, import_field_type_resolver.resolveRelationFieldType)({
11293
+ fieldType: (0, import_service_utils.hasOwnDefined)(changes, "fieldType") ? changes.fieldType : currentPublicFieldType,
11294
+ containerUse: current == null ? void 0 : current.use,
11295
+ field: fieldSource.field,
11296
+ dataSourceKey: (_l = fieldSource.fieldSettingsInit) == null ? void 0 : _l.dataSourceKey,
11297
+ getCollection: (dataSourceKey, collectionName) => this.getCollection(dataSourceKey, collectionName),
11298
+ fields: changes.fields,
11299
+ selectorFields: changes.selectorFields,
11300
+ titleField: (0, import_service_utils.hasOwnDefined)(wrapperChanges, "titleField") ? wrapperChanges.titleField : void 0,
11301
+ openMode: (0, import_service_utils.hasOwnDefined)(changes, "openMode") ? changes.openMode : void 0,
11302
+ popupSize: (0, import_service_utils.hasOwnDefined)(changes, "popupSize") ? changes.popupSize : void 0,
11303
+ pageSize: (0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? changes.pageSize : void 0,
11304
+ showIndex: (0, import_service_utils.hasOwnDefined)(changes, "showIndex") ? changes.showIndex : void 0,
11305
+ applyDefaults: shouldApplyResolverDefaults,
11306
+ context: "configure"
11307
+ });
11308
+ if (!fieldTypeResolution) {
11309
+ (0, import_errors.throwBadRequest)("flowSurfaces configure fieldType is required when configuring relation fields");
11310
+ }
11311
+ const shouldApplyFieldTypeDefaults = shouldApplyResolverDefaults;
11312
+ const shouldApplyRelationTitleField = (0, import_service_utils.hasOwnDefined)(wrapperChanges, "titleField") || shouldApplyFieldTypeDefaults;
11313
+ relationTitleFieldToApply = shouldApplyRelationTitleField ? fieldTypeResolution.titleField : void 0;
10936
11314
  const normalizedFieldComponentUse = await this.rebuildFieldSubModelOnServer({
10937
11315
  wrapperNode: current,
10938
11316
  innerField,
10939
- targetFieldUse: changes.fieldComponent,
11317
+ targetFieldUse: fieldTypeResolution.fieldUse,
10940
11318
  normalizedBinding,
10941
11319
  enabledPackages,
10942
11320
  transaction: options.transaction
10943
11321
  });
10944
- await this.syncFieldComponentStepParams(current, normalizedFieldComponentUse, options.transaction);
11322
+ effectiveInnerFieldUse = normalizedFieldComponentUse;
11323
+ await this.syncFieldTypeStepParams(current, normalizedFieldComponentUse, options.transaction);
11324
+ await this.applyResolvedRelationFieldType({
11325
+ fieldUid: innerUid,
11326
+ fieldUse: normalizedFieldComponentUse,
11327
+ targetCollection: fieldTypeResolution.targetCollection,
11328
+ relationFieldInit: fieldSource.fieldSettingsInit,
11329
+ fields: (0, import_service_utils.hasOwnDefined)(changes, "fields") || shouldApplyFieldTypeDefaults ? fieldTypeResolution.fields : void 0,
11330
+ selectorFields: (0, import_service_utils.hasOwnDefined)(changes, "selectorFields") || shouldApplyFieldTypeDefaults ? fieldTypeResolution.selectorFields : void 0,
11331
+ titleField: relationTitleFieldToApply,
11332
+ openMode: fieldTypeResolution.openMode,
11333
+ popupSize: fieldTypeResolution.popupSize,
11334
+ pageSize: fieldTypeResolution.pageSize,
11335
+ showIndex: fieldTypeResolution.showIndex,
11336
+ transaction: options.transaction
11337
+ });
10945
11338
  }
10946
- if (shouldSyncTitleField) {
11339
+ const effectiveSyncedTitleField = relationTitleFieldToApply ?? syncedTitleField;
11340
+ if ((shouldSyncTitleField || !import_lodash.default.isUndefined(relationTitleFieldToApply)) && this.supportsFieldTitleFieldProp(effectiveInnerFieldUse)) {
10947
11341
  if (!innerUid) {
10948
11342
  (0, import_errors.throwConflict)(
10949
11343
  `flowSurfaces configure field wrapper '${current == null ? void 0 : current.use}' cannot resolve inner field`,
@@ -10956,7 +11350,7 @@ class FlowSurfacesService {
10956
11350
  uid: innerUid
10957
11351
  },
10958
11352
  props: {
10959
- titleField: syncedTitleField
11353
+ titleField: effectiveSyncedTitleField
10960
11354
  }
10961
11355
  },
10962
11356
  options
@@ -11024,6 +11418,7 @@ class FlowSurfacesService {
11024
11418
  });
11025
11419
  const shouldSyncTitleField = titleFieldSyncDecision.shouldSync;
11026
11420
  const syncedTitleField = titleFieldSyncDecision.titleField;
11421
+ const canSyncInnerTitleField = this.supportsFieldTitleFieldProp(current == null ? void 0 : current.use);
11027
11422
  if ((parentWrapper == null ? void 0 : parentWrapper.uid) && canSyncWrapperTitleField && shouldSyncTitleField) {
11028
11423
  await this.updateSettings(
11029
11424
  {
@@ -11086,7 +11481,7 @@ class FlowSurfacesService {
11086
11481
  quickCreate: changes.quickCreate,
11087
11482
  displayStyle: changes.displayStyle,
11088
11483
  options: changes.options,
11089
- ...shouldSyncTitleField ? { titleField: syncedTitleField } : {},
11484
+ ...shouldSyncTitleField && canSyncInnerTitleField ? { titleField: syncedTitleField } : {},
11090
11485
  ...(0, import_service_utils.hasOwnDefined)(changes, "clickToOpen") || !import_lodash.default.isUndefined(changes.openView) ? { clickToOpen: effectiveClickToOpen } : {}
11091
11486
  }),
11092
11487
  stepParams: (0, import_service_utils.buildDefinedPayload)({
@@ -11153,6 +11548,7 @@ class FlowSurfacesService {
11153
11548
  return import_lodash.default.cloneDeep(value);
11154
11549
  }
11155
11550
  async configureActionNode(target, use, changes, options) {
11551
+ changes = await this.normalizeActionPanelActionChanges(changes, options);
11156
11552
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)(use);
11157
11553
  (0, import_service_utils.assertSupportedSimpleChanges)("action", changes, allowedKeys);
11158
11554
  const normalizedDefaultFilter = (0, import_service_utils.hasOwnDefined)(changes, "defaultFilter") ? this.normalizeFilterActionDefaultFilterValue(changes.defaultFilter) : void 0;
@@ -11375,6 +11771,21 @@ class FlowSurfacesService {
11375
11771
  }
11376
11772
  );
11377
11773
  }
11774
+ async normalizeActionPanelActionChanges(changes, options) {
11775
+ var _a;
11776
+ if (!(0, import_service_utils.hasOwnDefined)(changes, "type") || !((_a = options.current) == null ? void 0 : _a.uid)) {
11777
+ return changes;
11778
+ }
11779
+ const parentUid = options.current.parentId || await this.locator.findParentUid(options.current.uid, options.transaction);
11780
+ const parentNode = parentUid ? await this.repository.findModelById(parentUid, {
11781
+ transaction: options.transaction,
11782
+ includeAsyncNode: true
11783
+ }) : null;
11784
+ if ((parentNode == null ? void 0 : parentNode.use) !== "ActionPanelBlockModel") {
11785
+ return changes;
11786
+ }
11787
+ return import_lodash.default.omit(changes, ["type"]);
11788
+ }
11378
11789
  async buildFieldCatalog(target, options = {}) {
11379
11790
  const resolved = await this.locator.resolve(target, { transaction: options.transaction });
11380
11791
  const container = await this.surfaceContext.resolveFieldContainer(resolved.uid, options.transaction).catch(() => null);
@@ -11532,7 +11943,7 @@ class FlowSurfacesService {
11532
11943
  continue;
11533
11944
  }
11534
11945
  const fieldInterface = String((0, import_service_helpers.getFieldInterface)(field) || "").trim();
11535
- if (import_field_semantics.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
11946
+ if (import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
11536
11947
  continue;
11537
11948
  }
11538
11949
  const associationFieldName = (0, import_service_helpers.getFieldName)(field);
@@ -11856,6 +12267,222 @@ class FlowSurfacesService {
11856
12267
  }
11857
12268
  return null;
11858
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
+ }
11859
12486
  isFilterFormFieldPathAvailableForResource(resourceInit, fieldPath, associationPathName) {
11860
12487
  if (!(resourceInit == null ? void 0 : resourceInit.dataSourceKey) || !(resourceInit == null ? void 0 : resourceInit.collectionName) || !fieldPath) {
11861
12488
  return false;
@@ -11886,7 +12513,7 @@ class FlowSurfacesService {
11886
12513
  { transaction }
11887
12514
  );
11888
12515
  }
11889
- async removeFilterFormConnectConfig(filterModelUid, transaction) {
12516
+ async removeFilterSourceBindings(filterModelUid, transaction) {
11890
12517
  const blockGrid = await this.findOwningBlockGrid(filterModelUid, transaction);
11891
12518
  if (!(blockGrid == null ? void 0 : blockGrid.uid)) {
11892
12519
  return;
@@ -11904,7 +12531,7 @@ class FlowSurfacesService {
11904
12531
  { transaction }
11905
12532
  );
11906
12533
  }
11907
- async removeFilterFormTargetBindings(targetBlockUid, transaction) {
12534
+ async removeFilterTargetBindings(targetBlockUid, transaction) {
11908
12535
  const blockGrid = await this.findOwningBlockGrid(targetBlockUid, transaction);
11909
12536
  if (!(blockGrid == null ? void 0 : blockGrid.uid)) {
11910
12537
  return;
@@ -12005,7 +12632,7 @@ class FlowSurfacesService {
12005
12632
  const fieldInit = import_lodash.default.get(node, ["stepParams", "fieldSettings", "init"]) || {};
12006
12633
  const defaultTargetUid = import_lodash.default.get(node, ["stepParams", "filterFormItemSettings", "init", "defaultTargetUid"]);
12007
12634
  if (!(fieldInit == null ? void 0 : fieldInit.fieldPath) || !defaultTargetUid) {
12008
- await this.removeFilterFormConnectConfig(node.uid, transaction);
12635
+ await this.removeFilterSourceBindings(node.uid, transaction);
12009
12636
  return;
12010
12637
  }
12011
12638
  const parentUid = await this.locator.findParentUid(node.uid, transaction);
@@ -12020,7 +12647,7 @@ class FlowSurfacesService {
12020
12647
  if (!options.skipIfTargetUnavailable) {
12021
12648
  throw error;
12022
12649
  }
12023
- await this.removeFilterFormConnectConfig(node.uid, transaction);
12650
+ await this.removeFilterSourceBindings(node.uid, transaction);
12024
12651
  return null;
12025
12652
  });
12026
12653
  if (!target) {
@@ -12031,7 +12658,7 @@ class FlowSurfacesService {
12031
12658
  fieldInit.fieldPath,
12032
12659
  fieldInit.associationPathName
12033
12660
  )) {
12034
- await this.removeFilterFormConnectConfig(node.uid, transaction);
12661
+ await this.removeFilterSourceBindings(node.uid, transaction);
12035
12662
  return;
12036
12663
  }
12037
12664
  await this.persistFilterFormConnectConfig(
@@ -13730,6 +14357,19 @@ class FlowSurfacesService {
13730
14357
  );
13731
14358
  return (0, import_service_helpers.resolveFieldFromCollection)(targetCollection, titleFieldName) || input.field;
13732
14359
  }
14360
+ supportsFieldTitleFieldProp(use) {
14361
+ return (0, import_configure_options.getConfigureOptionKeysForUse)(use).includes("titleField");
14362
+ }
14363
+ normalizeFieldPropsForUse(use, props) {
14364
+ const normalizedProps = import_lodash.default.cloneDeep(props || {});
14365
+ if (this.supportsFieldTitleFieldProp(use)) {
14366
+ return normalizedProps;
14367
+ }
14368
+ if (Object.prototype.hasOwnProperty.call(normalizedProps, "titleField")) {
14369
+ delete normalizedProps.titleField;
14370
+ }
14371
+ return normalizedProps;
14372
+ }
13733
14373
  async ensureGridChild(parentUid, use, transaction) {
13734
14374
  const existing = await this.repository.findModelByParentId(parentUid, {
13735
14375
  transaction,
@@ -13909,7 +14549,7 @@ class FlowSurfacesService {
13909
14549
  );
13910
14550
  const associationInterface = (0, import_service_helpers.getFieldInterface)(parsed.associationField);
13911
14551
  const leafField = (0, import_service_helpers.resolveFieldFromCollection)(parsed.leafCollection, parsed.leafFieldPath);
13912
- const shouldBindAssociationValue = DISPLAY_FIELD_WRAPPER_USES.has(input.wrapperUse || "") && !!parsed.associationPathName && parsed.fieldPath !== parsed.associationPathName && import_field_semantics.MULTI_VALUE_ASSOCIATION_INTERFACES.has(associationInterface || "");
14552
+ const shouldBindAssociationValue = DISPLAY_FIELD_WRAPPER_USES.has(input.wrapperUse || "") && !!parsed.associationPathName && parsed.fieldPath !== parsed.associationPathName && import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(associationInterface || "");
13913
14553
  if (shouldBindAssociationValue) {
13914
14554
  const associationFieldPath = parsed.associationPathName;
13915
14555
  if (!associationFieldPath) {
@@ -13951,6 +14591,382 @@ class FlowSurfacesService {
13951
14591
  usesAssociationValueBinding: false
13952
14592
  };
13953
14593
  }
14594
+ getCollectionFieldOrBadRequest(collection, fieldPath, context) {
14595
+ const field = (0, import_service_helpers.resolveFieldFromCollection)(collection, fieldPath);
14596
+ if (!field) {
14597
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${context} field '${fieldPath}' does not exist on relation target collection`);
14598
+ }
14599
+ return field;
14600
+ }
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;
14615
+ return (0, import_service_utils.buildDefinedPayload)({
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
14620
+ });
14621
+ }
14622
+ buildRelationTargetTableColumnNode(input) {
14623
+ const field = this.getCollectionFieldOrBadRequest(input.collection, input.fieldPath, "fieldType.fields");
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";
14625
+ const title = (0, import_service_helpers.getFieldTitle)(field);
14626
+ const fieldInit = this.buildRelationTargetFieldInit({
14627
+ targetCollection: input.collection,
14628
+ targetFieldPath: input.fieldPath,
14629
+ relationFieldInit: input.relationFieldInit
14630
+ });
14631
+ return {
14632
+ uid: (0, import_utils.uid)(),
14633
+ use: input.columnUse,
14634
+ props: (0, import_service_utils.buildDefinedPayload)({
14635
+ title,
14636
+ dataIndex: (0, import_service_helpers.getFieldName)(field)
14637
+ }),
14638
+ stepParams: {
14639
+ fieldSettings: {
14640
+ init: fieldInit
14641
+ },
14642
+ ...input.columnUse === "TableColumnModel" ? {
14643
+ tableColumnSettings: {
14644
+ title: {
14645
+ title
14646
+ }
14647
+ }
14648
+ } : {}
14649
+ },
14650
+ subModels: {
14651
+ field: {
14652
+ uid: (0, import_utils.uid)(),
14653
+ use: fieldUse,
14654
+ props: this.normalizeFieldPropsForUse(
14655
+ fieldUse,
14656
+ (0, import_service_utils.getFieldBindingDefaultProps)("TableColumnModel", fieldUse, field)
14657
+ ),
14658
+ stepParams: {
14659
+ fieldSettings: {
14660
+ init: fieldInit
14661
+ },
14662
+ fieldBinding: {
14663
+ use: fieldUse
14664
+ }
14665
+ }
14666
+ }
14667
+ }
14668
+ };
14669
+ }
14670
+ buildRelationTargetGridItemNode(input) {
14671
+ const field = this.getCollectionFieldOrBadRequest(input.collection, input.fieldPath, "fieldType.fields");
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";
14673
+ const title = (0, import_service_helpers.getFieldTitle)(field);
14674
+ const fieldInit = this.buildRelationTargetFieldInit({
14675
+ targetCollection: input.collection,
14676
+ targetFieldPath: input.fieldPath,
14677
+ relationFieldInit: input.relationFieldInit
14678
+ });
14679
+ return {
14680
+ uid: (0, import_utils.uid)(),
14681
+ use: input.wrapperUse,
14682
+ props: (0, import_service_utils.buildDefinedPayload)({
14683
+ label: title
14684
+ }),
14685
+ stepParams: {
14686
+ fieldSettings: {
14687
+ init: fieldInit
14688
+ }
14689
+ },
14690
+ subModels: {
14691
+ field: {
14692
+ uid: (0, import_utils.uid)(),
14693
+ use: fieldUse,
14694
+ props: this.normalizeFieldPropsForUse(
14695
+ fieldUse,
14696
+ (0, import_service_utils.getFieldBindingDefaultProps)(input.wrapperUse, fieldUse, field)
14697
+ ),
14698
+ stepParams: {
14699
+ fieldSettings: {
14700
+ init: fieldInit
14701
+ },
14702
+ fieldBinding: {
14703
+ use: fieldUse
14704
+ }
14705
+ }
14706
+ }
14707
+ }
14708
+ };
14709
+ }
14710
+ async replaceFieldSubModelArray(input) {
14711
+ var _a, _b;
14712
+ const parentNode = await this.repository.findModelById(input.parentUid, {
14713
+ transaction: input.transaction,
14714
+ includeAsyncNode: true
14715
+ });
14716
+ const keptChildren = [];
14717
+ for (const child of import_lodash.default.castArray(((_a = parentNode == null ? void 0 : parentNode.subModels) == null ? void 0 : _a[input.subKey]) || [])) {
14718
+ if (!(child == null ? void 0 : child.uid)) {
14719
+ continue;
14720
+ }
14721
+ if ((_b = input.keepUses) == null ? void 0 : _b.includes(child.use)) {
14722
+ keptChildren.push(child);
14723
+ continue;
14724
+ }
14725
+ await this.removeNodeTreeWithBindings(child.uid, input.transaction);
14726
+ }
14727
+ for (const child of keptChildren.reverse()) {
14728
+ await this.repository.attach(
14729
+ child.uid,
14730
+ {
14731
+ parentId: input.parentUid,
14732
+ subKey: input.subKey,
14733
+ subType: "array",
14734
+ position: "first"
14735
+ },
14736
+ { transaction: input.transaction }
14737
+ );
14738
+ }
14739
+ for (const child of input.children) {
14740
+ await this.repository.upsertModel(
14741
+ {
14742
+ parentId: input.parentUid,
14743
+ subKey: input.subKey,
14744
+ subType: "array",
14745
+ ...child
14746
+ },
14747
+ { transaction: input.transaction }
14748
+ );
14749
+ }
14750
+ }
14751
+ buildPopupSubTableActionsColumnNode(existing) {
14752
+ var _a, _b;
14753
+ const defaultActionColumn = import_lodash.default.cloneDeep(
14754
+ (_b = (_a = (0, import_builder.getStandaloneFieldDefaults)("PopupSubTableFieldModel").subModels) == null ? void 0 : _a.subTableColumns) == null ? void 0 : _b[0]
14755
+ );
14756
+ return {
14757
+ ...defaultActionColumn || {
14758
+ use: "PopupSubTableActionsColumnModel"
14759
+ },
14760
+ ...existing || {},
14761
+ uid: (existing == null ? void 0 : existing.uid) || (defaultActionColumn == null ? void 0 : defaultActionColumn.uid) || (0, import_utils.uid)()
14762
+ };
14763
+ }
14764
+ async ensureFieldGridSubModel(input) {
14765
+ var _a;
14766
+ const fieldNode = await this.repository.findModelById(input.fieldUid, {
14767
+ transaction: input.transaction,
14768
+ includeAsyncNode: true
14769
+ });
14770
+ const existingGrid = (_a = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _a.grid;
14771
+ if (existingGrid == null ? void 0 : existingGrid.uid) {
14772
+ return existingGrid.uid;
14773
+ }
14774
+ const gridUid = (0, import_utils.uid)();
14775
+ await this.repository.upsertModel(
14776
+ {
14777
+ uid: gridUid,
14778
+ parentId: input.fieldUid,
14779
+ subKey: "grid",
14780
+ subType: "object",
14781
+ use: input.gridUse
14782
+ },
14783
+ { transaction: input.transaction }
14784
+ );
14785
+ return gridUid;
14786
+ }
14787
+ async applyResolvedRelationFieldType(input) {
14788
+ var _a;
14789
+ if (input.titleField || !import_lodash.default.isUndefined(input.pageSize) || !import_lodash.default.isUndefined(input.showIndex)) {
14790
+ const fieldNode = await this.repository.findModelById(input.fieldUid, {
14791
+ transaction: input.transaction,
14792
+ includeAsyncNode: true
14793
+ });
14794
+ const props = (0, import_service_utils.buildDefinedPayload)({
14795
+ ...input.titleField && this.supportsFieldTitleFieldProp(input.fieldUse) ? { titleField: input.titleField } : {},
14796
+ pageSize: input.pageSize,
14797
+ showIndex: input.showIndex
14798
+ });
14799
+ if (Object.keys(props).length) {
14800
+ await this.repository.patch(
14801
+ {
14802
+ uid: input.fieldUid,
14803
+ props: {
14804
+ ...(fieldNode == null ? void 0 : fieldNode.props) || {},
14805
+ ...props
14806
+ }
14807
+ },
14808
+ { transaction: input.transaction }
14809
+ );
14810
+ }
14811
+ }
14812
+ const fields = input.fields;
14813
+ if ((0, import_field_type_resolver.usesNestedRelationFields)(input.fieldUse) && fields) {
14814
+ if (["SubTableFieldModel", "DisplaySubTableFieldModel"].includes(input.fieldUse)) {
14815
+ await this.replaceFieldSubModelArray({
14816
+ parentUid: input.fieldUid,
14817
+ subKey: "columns",
14818
+ children: fields.map(
14819
+ (fieldPath) => this.buildRelationTargetTableColumnNode({
14820
+ collection: input.targetCollection,
14821
+ fieldPath,
14822
+ columnUse: input.fieldUse === "SubTableFieldModel" ? "SubTableColumnModel" : "TableColumnModel",
14823
+ relationFieldInit: input.relationFieldInit
14824
+ })
14825
+ ),
14826
+ transaction: input.transaction
14827
+ });
14828
+ } else if (input.fieldUse === "PopupSubTableFieldModel") {
14829
+ const fieldNode = await this.repository.findModelById(input.fieldUid, {
14830
+ transaction: input.transaction,
14831
+ includeAsyncNode: true
14832
+ });
14833
+ const existingActionsColumn = import_lodash.default.castArray(((_a = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _a.subTableColumns) || []).find(
14834
+ (item) => (item == null ? void 0 : item.use) === "PopupSubTableActionsColumnModel"
14835
+ );
14836
+ await this.replaceFieldSubModelArray({
14837
+ parentUid: input.fieldUid,
14838
+ subKey: "subTableColumns",
14839
+ children: [
14840
+ this.buildPopupSubTableActionsColumnNode(existingActionsColumn),
14841
+ ...fields.map(
14842
+ (fieldPath) => this.buildRelationTargetTableColumnNode({
14843
+ collection: input.targetCollection,
14844
+ fieldPath,
14845
+ columnUse: "TableColumnModel",
14846
+ relationFieldInit: input.relationFieldInit
14847
+ })
14848
+ )
14849
+ ],
14850
+ transaction: input.transaction
14851
+ });
14852
+ } else {
14853
+ const gridUse = ["SubFormFieldModel", "SubFormListFieldModel"].includes(input.fieldUse) ? "FormGridModel" : "DetailsGridModel";
14854
+ const wrapperUse = ["SubFormFieldModel", "SubFormListFieldModel"].includes(input.fieldUse) ? "FormItemModel" : "DetailsItemModel";
14855
+ const gridUid = await this.ensureFieldGridSubModel({
14856
+ fieldUid: input.fieldUid,
14857
+ gridUse,
14858
+ transaction: input.transaction
14859
+ });
14860
+ await this.replaceFieldSubModelArray({
14861
+ parentUid: gridUid,
14862
+ subKey: "items",
14863
+ children: fields.map(
14864
+ (fieldPath) => this.buildRelationTargetGridItemNode({
14865
+ collection: input.targetCollection,
14866
+ fieldPath,
14867
+ wrapperUse,
14868
+ relationFieldInit: input.relationFieldInit
14869
+ })
14870
+ ),
14871
+ transaction: input.transaction
14872
+ });
14873
+ }
14874
+ }
14875
+ if (input.fieldUse === "RecordPickerFieldModel") {
14876
+ await this.applyRecordPickerFieldTypeSettings(input);
14877
+ }
14878
+ }
14879
+ async applyRecordPickerFieldTypeSettings(input) {
14880
+ var _a, _b, _c;
14881
+ const fieldNode = await this.repository.findModelById(input.fieldUid, {
14882
+ transaction: input.transaction,
14883
+ includeAsyncNode: true
14884
+ });
14885
+ const openView = (0, import_service_utils.buildDefinedPayload)({
14886
+ mode: input.openMode,
14887
+ size: input.popupSize,
14888
+ pageModelClass: "ChildPageModel",
14889
+ dataSourceKey: ((_a = input.targetCollection) == null ? void 0 : _a.dataSourceKey) || "main",
14890
+ collectionName: (0, import_service_helpers.getCollectionName)(input.targetCollection)
14891
+ });
14892
+ if (Object.keys(openView).length > 2) {
14893
+ await this.repository.patch(
14894
+ {
14895
+ uid: input.fieldUid,
14896
+ stepParams: import_lodash.default.merge({}, (fieldNode == null ? void 0 : fieldNode.stepParams) || {}, {
14897
+ popupSettings: {
14898
+ openView
14899
+ }
14900
+ })
14901
+ },
14902
+ { transaction: input.transaction }
14903
+ );
14904
+ }
14905
+ if (!input.selectorFields) {
14906
+ return;
14907
+ }
14908
+ let grid = await this.repository.findModelByParentId(input.fieldUid, {
14909
+ transaction: input.transaction,
14910
+ subKey: "grid-block",
14911
+ includeAsyncNode: true
14912
+ });
14913
+ if (!(grid == null ? void 0 : grid.uid)) {
14914
+ const gridUid = (0, import_utils.uid)();
14915
+ await this.repository.upsertModel(
14916
+ {
14917
+ uid: gridUid,
14918
+ parentId: input.fieldUid,
14919
+ subKey: "grid-block",
14920
+ subType: "object",
14921
+ use: "BlockGridModel"
14922
+ },
14923
+ { transaction: input.transaction }
14924
+ );
14925
+ grid = await this.repository.findModelById(gridUid, {
14926
+ transaction: input.transaction,
14927
+ includeAsyncNode: true
14928
+ });
14929
+ }
14930
+ if (!(grid == null ? void 0 : grid.uid)) {
14931
+ return;
14932
+ }
14933
+ const existingTable = import_lodash.default.castArray(((_b = grid == null ? void 0 : grid.subModels) == null ? void 0 : _b.items) || []).find(
14934
+ (item) => (item == null ? void 0 : item.use) === "TableBlockModel"
14935
+ );
14936
+ const tableUid = (existingTable == null ? void 0 : existingTable.uid) || (0, import_utils.uid)();
14937
+ if (!(existingTable == null ? void 0 : existingTable.uid)) {
14938
+ await this.repository.upsertModel(
14939
+ {
14940
+ uid: tableUid,
14941
+ parentId: grid.uid,
14942
+ subKey: "items",
14943
+ subType: "array",
14944
+ use: "TableBlockModel",
14945
+ stepParams: {
14946
+ resourceSettings: {
14947
+ init: {
14948
+ dataSourceKey: ((_c = input.targetCollection) == null ? void 0 : _c.dataSourceKey) || "main",
14949
+ collectionName: (0, import_service_helpers.getCollectionName)(input.targetCollection)
14950
+ }
14951
+ }
14952
+ }
14953
+ },
14954
+ { transaction: input.transaction }
14955
+ );
14956
+ }
14957
+ await this.replaceFieldSubModelArray({
14958
+ parentUid: tableUid,
14959
+ subKey: "columns",
14960
+ children: input.selectorFields.map(
14961
+ (fieldPath) => this.buildRelationTargetTableColumnNode({
14962
+ collection: input.targetCollection,
14963
+ fieldPath,
14964
+ columnUse: "TableColumnModel"
14965
+ })
14966
+ ),
14967
+ transaction: input.transaction
14968
+ });
14969
+ }
13954
14970
  buildExactFieldSettingsInitPayload(input) {
13955
14971
  return (0, import_service_utils.buildDefinedPayload)({
13956
14972
  dataSourceKey: input.dataSourceKey,
@@ -14058,7 +15074,7 @@ class FlowSurfacesService {
14058
15074
  const targetFieldUse = input.targetFieldUse;
14059
15075
  const normalizedTargetUse = String(targetFieldUse || "").trim();
14060
15076
  if (!normalizedTargetUse) {
14061
- (0, import_errors.throwBadRequest)("flowSurfaces configure fieldComponent cannot be empty");
15077
+ (0, import_errors.throwBadRequest)("flowSurfaces configure fieldType cannot be empty");
14062
15078
  }
14063
15079
  const normalizedWrapperUse = String(wrapperUse || "").trim();
14064
15080
  const containerUse = normalizedWrapperUse === "FormAssociationItemModel" ? "DetailsItemModel" : normalizedWrapperUse;
@@ -14073,7 +15089,7 @@ class FlowSurfacesService {
14073
15089
  });
14074
15090
  if (!(supportedFieldUses == null ? void 0 : supportedFieldUses.has(normalizedTargetUse))) {
14075
15091
  (0, import_errors.throwBadRequest)(
14076
- `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent '${normalizedTargetUse}'`
15092
+ `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType '${normalizedTargetUse}'`
14077
15093
  );
14078
15094
  }
14079
15095
  return normalizedTargetUse;
@@ -14084,7 +15100,7 @@ class FlowSurfacesService {
14084
15100
  });
14085
15101
  if (!(contract == null ? void 0 : contract.fieldUse)) {
14086
15102
  (0, import_errors.throwBadRequest)(
14087
- `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent '${normalizedTargetUse}'`
15103
+ `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType '${normalizedTargetUse}'`
14088
15104
  );
14089
15105
  }
14090
15106
  return contract.fieldUse;
@@ -14100,7 +15116,7 @@ class FlowSurfacesService {
14100
15116
  });
14101
15117
  if (!(supportedFieldUses == null ? void 0 : supportedFieldUses.has(normalizedTargetUse))) {
14102
15118
  (0, import_errors.throwBadRequest)(
14103
- `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent '${normalizedTargetUse}'`
15119
+ `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType '${normalizedTargetUse}'`
14104
15120
  );
14105
15121
  }
14106
15122
  return normalizedTargetUse;
@@ -14111,19 +15127,22 @@ class FlowSurfacesService {
14111
15127
  });
14112
15128
  if (!(contract == null ? void 0 : contract.fieldUse)) {
14113
15129
  (0, import_errors.throwBadRequest)(
14114
- `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent '${normalizedTargetUse}'`
15130
+ `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType '${normalizedTargetUse}'`
14115
15131
  );
14116
15132
  }
14117
15133
  return contract.fieldUse;
14118
15134
  }
14119
- (0, import_errors.throwBadRequest)(`flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent`);
15135
+ (0, import_errors.throwBadRequest)(`flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType`);
14120
15136
  }
14121
- async syncFieldComponentStepParams(wrapperNode, targetFieldUse, transaction) {
15137
+ async syncFieldTypeStepParams(wrapperNode, targetFieldUse, transaction) {
14122
15138
  const flowDomain = this.inferFieldComponentFlowDomain(wrapperNode == null ? void 0 : wrapperNode.use);
14123
15139
  if (!flowDomain || !(wrapperNode == null ? void 0 : wrapperNode.uid)) {
14124
15140
  return;
14125
15141
  }
14126
- const nextStepParams = import_lodash.default.merge({}, wrapperNode.stepParams || {}, {
15142
+ const latestWrapper = await this.repository.findModelById(wrapperNode.uid, {
15143
+ transaction
15144
+ });
15145
+ const nextStepParams = import_lodash.default.merge({}, (latestWrapper == null ? void 0 : latestWrapper.stepParams) || wrapperNode.stepParams || {}, {
14127
15146
  [flowDomain.flowKey]: {
14128
15147
  [flowDomain.stepKey]: {
14129
15148
  use: targetFieldUse
@@ -14139,7 +15158,7 @@ class FlowSurfacesService {
14139
15158
  );
14140
15159
  }
14141
15160
  async rebuildFieldSubModelOnServer(input) {
14142
- var _a, _b, _c, _d, _e;
15161
+ var _a, _b, _c, _d, _e, _f;
14143
15162
  const innerField = input.innerField;
14144
15163
  if (!(innerField == null ? void 0 : innerField.uid)) {
14145
15164
  (0, import_errors.throwConflict)(
@@ -14155,16 +15174,38 @@ class FlowSurfacesService {
14155
15174
  dataSourceKey: (_c = fieldSource.fieldSettingsInit) == null ? void 0 : _c.dataSourceKey,
14156
15175
  enabledPackages: input.enabledPackages
14157
15176
  });
15177
+ if (innerField.use === normalizedTargetUse) {
15178
+ await this.repository.patch(
15179
+ {
15180
+ uid: innerField.uid,
15181
+ stepParams: import_lodash.default.merge({}, innerField.stepParams || {}, {
15182
+ fieldBinding: {
15183
+ use: normalizedTargetUse
15184
+ },
15185
+ fieldSettings: {
15186
+ init: fieldSource.fieldSettingsInit
15187
+ }
15188
+ })
15189
+ },
15190
+ { transaction: input.transaction }
15191
+ );
15192
+ return normalizedTargetUse;
15193
+ }
14158
15194
  const defaultProps = (0, import_service_utils.getFieldBindingDefaultProps)((_d = input.wrapperNode) == null ? void 0 : _d.use, normalizedTargetUse, fieldSource.field);
15195
+ const fieldDefaults = (0, import_builder.getStandaloneFieldDefaults)(normalizedTargetUse);
14159
15196
  const shouldPreservePatternFormField = ((_e = input.wrapperNode) == null ? void 0 : _e.use) === "PatternFormItemModel";
15197
+ const preservedPopupPageSubModel = ((_f = input.innerField) == null ? void 0 : _f.subModels) && Object.prototype.hasOwnProperty.call(input.innerField.subModels, "page") ? {
15198
+ page: import_lodash.default.cloneDeep(input.innerField.subModels.page)
15199
+ } : {};
15200
+ const nextSubModels = {
15201
+ ...fieldDefaults.subModels ? import_lodash.default.cloneDeep(fieldDefaults.subModels) : {},
15202
+ ...preservedPopupPageSubModel
15203
+ };
14160
15204
  const nextFieldNode = {
14161
15205
  uid: innerField.uid,
14162
15206
  use: shouldPreservePatternFormField ? "PatternFormFieldModel" : normalizedTargetUse,
14163
15207
  props: import_lodash.default.pickBy(
14164
- {
14165
- ...innerField.props || {},
14166
- ...defaultProps
14167
- },
15208
+ this.normalizeFieldPropsForUse(normalizedTargetUse, { ...innerField.props || {}, ...defaultProps }),
14168
15209
  (value) => !import_lodash.default.isUndefined(value)
14169
15210
  ),
14170
15211
  decoratorProps: import_lodash.default.cloneDeep(innerField.decoratorProps || {}),
@@ -14176,7 +15217,8 @@ class FlowSurfacesService {
14176
15217
  fieldSettings: {
14177
15218
  init: fieldSource.fieldSettingsInit
14178
15219
  }
14179
- })
15220
+ }),
15221
+ subModels: nextSubModels
14180
15222
  };
14181
15223
  await this.repository.patch(nextFieldNode, { transaction: input.transaction });
14182
15224
  return normalizedTargetUse;