@nocobase/plugin-flow-engine 2.1.0-alpha.23 → 2.1.0-alpha.25

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 (49) hide show
  1. package/dist/ai/ai-employees/nathan/skills/frontend-developer/SKILLS.md +2 -2
  2. package/dist/externalVersion.js +10 -10
  3. package/dist/node_modules/ses/package.json +1 -1
  4. package/dist/node_modules/zod/package.json +1 -1
  5. package/dist/server/flow-surfaces/action-scope.d.ts +1 -0
  6. package/dist/server/flow-surfaces/action-scope.js +4 -0
  7. package/dist/server/flow-surfaces/apply/compiler.js +4 -2
  8. package/dist/server/flow-surfaces/association-interfaces.d.ts +10 -0
  9. package/dist/server/flow-surfaces/association-interfaces.js +39 -0
  10. package/dist/server/flow-surfaces/association-title-field.d.ts +1 -1
  11. package/dist/server/flow-surfaces/association-title-field.js +38 -4
  12. package/dist/server/flow-surfaces/blueprint/compile-blocks.js +72 -5
  13. package/dist/server/flow-surfaces/blueprint/public-types.d.ts +9 -1
  14. package/dist/server/flow-surfaces/builder.d.ts +27 -1
  15. package/dist/server/flow-surfaces/builder.js +105 -5
  16. package/dist/server/flow-surfaces/catalog.d.ts +2 -1
  17. package/dist/server/flow-surfaces/catalog.js +316 -119
  18. package/dist/server/flow-surfaces/compose-compiler.d.ts +8 -0
  19. package/dist/server/flow-surfaces/compose-compiler.js +9 -1
  20. package/dist/server/flow-surfaces/configure-options.js +72 -6
  21. package/dist/server/flow-surfaces/core-field-default-bindings.d.ts +12 -0
  22. package/dist/server/flow-surfaces/core-field-default-bindings.js +157 -0
  23. package/dist/server/flow-surfaces/default-action-popup.js +2 -2
  24. package/dist/server/flow-surfaces/default-block-actions.js +24 -0
  25. package/dist/server/flow-surfaces/field-binding-registry.d.ts +1 -0
  26. package/dist/server/flow-surfaces/field-binding-registry.js +5 -0
  27. package/dist/server/flow-surfaces/field-semantics.d.ts +1 -1
  28. package/dist/server/flow-surfaces/field-semantics.js +7 -4
  29. package/dist/server/flow-surfaces/field-type-resolver.d.ts +46 -0
  30. package/dist/server/flow-surfaces/field-type-resolver.js +322 -0
  31. package/dist/server/flow-surfaces/index.js +61 -2
  32. package/dist/server/flow-surfaces/node-use-sets.js +4 -0
  33. package/dist/server/flow-surfaces/placement.js +3 -0
  34. package/dist/server/flow-surfaces/public-data-surface-default-filter.d.ts +4 -0
  35. package/dist/server/flow-surfaces/public-data-surface-default-filter.js +45 -4
  36. package/dist/server/flow-surfaces/service-helpers.js +3 -70
  37. package/dist/server/flow-surfaces/service-utils.d.ts +13 -1
  38. package/dist/server/flow-surfaces/service-utils.js +58 -6
  39. package/dist/server/flow-surfaces/service.d.ts +59 -2
  40. package/dist/server/flow-surfaces/service.js +2269 -234
  41. package/dist/server/flow-surfaces/support-matrix.d.ts +1 -1
  42. package/dist/server/flow-surfaces/support-matrix.js +23 -0
  43. package/dist/server/flow-surfaces/surface-context.js +8 -5
  44. package/dist/swagger/flow-surfaces.d.ts +173 -2
  45. package/dist/swagger/flow-surfaces.examples.d.ts +59 -15
  46. package/dist/swagger/flow-surfaces.examples.js +69 -11
  47. package/dist/swagger/flow-surfaces.js +86 -17
  48. package/dist/swagger/index.d.ts +173 -2
  49. 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]);
@@ -105,6 +107,7 @@ const COMPOSE_FIELD_GRID_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "e
105
107
  const COMPOSE_FIELD_GROUP_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "editForm", "details"]);
106
108
  const LIST_BLOCK_USES = /* @__PURE__ */ new Set(["ListBlockModel"]);
107
109
  const GRID_CARD_BLOCK_USES = /* @__PURE__ */ new Set(["GridCardBlockModel"]);
110
+ const KANBAN_BLOCK_USES = /* @__PURE__ */ new Set(["KanbanBlockModel"]);
108
111
  const DEFAULT_CALENDAR_TITLE_FIELD_INTERFACES = ["input", "select", "phone", "email", "radioGroup"];
109
112
  const DEFAULT_CALENDAR_COLOR_FIELD_INTERFACES = ["select", "radioGroup"];
110
113
  const DEFAULT_CALENDAR_DATE_TIME_FIELD_TYPES = [
@@ -116,10 +119,19 @@ const DEFAULT_CALENDAR_DATE_TIME_FIELD_TYPES = [
116
119
  "createdAt",
117
120
  "updatedAt"
118
121
  ];
122
+ const CALENDAR_DEFAULT_VIEWS = /* @__PURE__ */ new Set(["month", "week", "day"]);
123
+ const CALENDAR_WEEK_STARTS = /* @__PURE__ */ new Set([0, 1]);
119
124
  const CALENDAR_POPUP_ACTION_KEYS = ["quickCreateAction", "eventViewAction"];
125
+ const KANBAN_POPUP_ACTION_UID_SUFFIX_BY_KEY = {
126
+ quickCreateAction: "-quick-create-action",
127
+ cardViewAction: "-card-view-action"
128
+ };
129
+ const KANBAN_POPUP_ACTION_KEYS = Object.keys(KANBAN_POPUP_ACTION_UID_SUFFIX_BY_KEY);
120
130
  const CANONICAL_BLOCK_HEADER_USES = /* @__PURE__ */ new Set([
121
131
  "TableBlockModel",
122
132
  "CalendarBlockModel",
133
+ "TreeBlockModel",
134
+ "KanbanBlockModel",
123
135
  "FormBlockModel",
124
136
  "CreateFormModel",
125
137
  "EditFormModel",
@@ -133,7 +145,8 @@ const CANONICAL_BLOCK_HEADER_USES = /* @__PURE__ */ new Set([
133
145
  "MapBlockModel",
134
146
  "CommentsBlockModel"
135
147
  ]);
136
- const LIST_LIKE_COMPOSE_BLOCK_TYPES = /* @__PURE__ */ new Set(["list", "gridCard"]);
148
+ const CARD_FIELD_COMPOSE_BLOCK_TYPES = /* @__PURE__ */ new Set(["list", "gridCard", "kanban"]);
149
+ const RECORD_ACTION_COMPOSE_BLOCK_TYPES = /* @__PURE__ */ new Set(["list", "gridCard"]);
137
150
  const GRID_SETTINGS_FLOW_KEY = "gridSettings";
138
151
  const GRID_SETTINGS_LAYOUT_STEP_KEY = "grid";
139
152
  const OPEN_VIEW_MODE_ALIASES = {
@@ -144,6 +157,8 @@ const OPEN_VIEW_SUPPORTED_MODES = /* @__PURE__ */ new Set(["drawer", "dialog", "
144
157
  const FILTER_TARGET_BLOCK_USES = /* @__PURE__ */ new Set([
145
158
  "TableBlockModel",
146
159
  "CalendarBlockModel",
160
+ "TreeBlockModel",
161
+ "KanbanBlockModel",
147
162
  "DetailsBlockModel",
148
163
  "ListBlockModel",
149
164
  "GridCardBlockModel",
@@ -193,6 +208,8 @@ const UI_FIELD_MENU_DETAILS_OWNER_USES = /* @__PURE__ */ new Set([
193
208
  "DetailsBlockModel",
194
209
  "GridCardBlockModel",
195
210
  "GridCardItemModel",
211
+ "KanbanBlockModel",
212
+ "KanbanCardItemModel",
196
213
  ...import_approval.APPROVAL_DETAILS_BLOCK_USES,
197
214
  ...import_approval.APPROVAL_DETAILS_GRID_USES
198
215
  ]);
@@ -221,6 +238,8 @@ const POPUP_ACTION_USES = /* @__PURE__ */ new Set([
221
238
  "PopupCollectionActionModel",
222
239
  "CalendarQuickCreateActionModel",
223
240
  "CalendarEventViewActionModel",
241
+ "KanbanQuickCreateActionModel",
242
+ "KanbanCardViewActionModel",
224
243
  "DuplicateActionModel",
225
244
  "AddChildActionModel",
226
245
  "MailSendActionModel"
@@ -230,6 +249,7 @@ const POPUP_HOST_DEFAULT_RECORD_CONTEXT_ACTION_USES = /* @__PURE__ */ new Set([
230
249
  "EditActionModel",
231
250
  "PopupCollectionActionModel",
232
251
  "CalendarEventViewActionModel",
252
+ "KanbanCardViewActionModel",
233
253
  "AddChildActionModel",
234
254
  "DuplicateActionModel"
235
255
  ]);
@@ -277,6 +297,8 @@ const POPUP_COLLECTION_BLOCK_SCENES = {
277
297
  CommentsBlockModel: ["one", "many"],
278
298
  TableBlockModel: ["many"],
279
299
  CalendarBlockModel: ["many"],
300
+ TreeBlockModel: ["filter"],
301
+ KanbanBlockModel: ["many"],
280
302
  ListBlockModel: ["many"],
281
303
  GridCardBlockModel: ["many"],
282
304
  MapBlockModel: ["many"],
@@ -829,7 +851,9 @@ class FlowSurfacesService {
829
851
  }
830
852
  const target = import_lodash.default.isUndefined(input == null ? void 0 : input.target) ? void 0 : this.normalizeWriteTarget("catalog", input == null ? void 0 : input.target, input);
831
853
  const resolved = target ? await this.locator.resolve(target, options) : null;
832
- const node = resolved ? await this.loadResolvedNode(resolved, options.transaction) : null;
854
+ const node = resolved ? await this.loadResolvedNode(resolved, options.transaction, {
855
+ persistCalendarPopupHosts: false
856
+ }) : null;
833
857
  const popupProfile = target ? await this.resolvePopupBlockProfile(target.uid, resolved, node, options.transaction) : null;
834
858
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
835
859
  const expand = new Set((0, import_catalog_smart.normalizeCatalogExpand)("catalog", input == null ? void 0 : input.expand));
@@ -932,8 +956,8 @@ class FlowSurfacesService {
932
956
  return this.patchResolvedNodeConfigureOptions(node, projected, enabledPackages);
933
957
  }
934
958
  patchResolvedNodeConfigureOptions(node, projected, enabledPackages) {
935
- var _a, _b, _c;
936
- if (!((_a = projected == null ? void 0 : projected.configureOptions) == null ? void 0 : _a.fieldComponent) || !(node == null ? void 0 : node.use)) {
959
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
960
+ if (!((_a = projected == null ? void 0 : projected.configureOptions) == null ? void 0 : _a.fieldType) || !(node == null ? void 0 : node.use)) {
937
961
  return projected;
938
962
  }
939
963
  try {
@@ -948,20 +972,98 @@ class FlowSurfacesService {
948
972
  if (!(supportedFieldUses == null ? void 0 : supportedFieldUses.size)) {
949
973
  return projected;
950
974
  }
975
+ const supportedFieldTypes = Array.from(supportedFieldUses).map((use) => (0, import_field_type_resolver.getPublicFieldTypeForUse)(use)).filter(Boolean);
951
976
  const configureOptions = import_lodash.default.cloneDeep(projected.configureOptions || {});
952
- configureOptions.fieldComponent = {
953
- type: ((_c = configureOptions.fieldComponent) == null ? void 0 : _c.type) || "string",
954
- ...configureOptions.fieldComponent || {},
955
- enum: Array.from(supportedFieldUses)
977
+ configureOptions.fieldType = {
978
+ type: ((_c = configureOptions.fieldType) == null ? void 0 : _c.type) || "string",
979
+ ...configureOptions.fieldType || {},
980
+ enum: Array.from(new Set(supportedFieldTypes))
956
981
  };
982
+ const innerField = ((_d = node == null ? void 0 : node.subModels) == null ? void 0 : _d.field) || node;
983
+ const relationFieldTypes = Array.from(new Set(supportedFieldTypes));
984
+ const defaultTitleField = this.getAssociationDefaultTitleFieldName(
985
+ fieldSource.field,
986
+ (_e = fieldSource.fieldSettingsInit) == null ? void 0 : _e.dataSourceKey
987
+ );
957
988
  return {
958
989
  ...projected,
959
- configureOptions
990
+ configureOptions,
991
+ relation: {
992
+ ...projected.relation,
993
+ fieldTypes: relationFieldTypes,
994
+ current: (0, import_service_utils.buildDefinedPayload)({
995
+ 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)),
996
+ fields: this.collectRelationNestedFieldPaths(innerField),
997
+ selectorFields: this.collectRelationSelectorFieldPaths(innerField),
998
+ 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)
999
+ }),
1000
+ defaults: (0, import_service_utils.buildDefinedPayload)({
1001
+ titleField: defaultTitleField
1002
+ }),
1003
+ candidates: this.buildRelationFieldTypeCandidates(relationFieldTypes, defaultTitleField),
1004
+ configureOptions
1005
+ }
960
1006
  };
961
1007
  } catch {
962
1008
  return projected;
963
1009
  }
964
1010
  }
1011
+ buildRelationFieldTypeCandidates(fieldTypes, defaultTitleField) {
1012
+ return fieldTypes.map((fieldType) => {
1013
+ const defaults = {
1014
+ titleField: defaultTitleField
1015
+ };
1016
+ if (["subForm", "subFormList", "subDetails", "subDetailsList", "subTable", "popupSubTable"].includes(fieldType) && defaultTitleField) {
1017
+ defaults.fields = [defaultTitleField];
1018
+ }
1019
+ if (fieldType === "picker" && defaultTitleField) {
1020
+ defaults.selectorFields = [defaultTitleField];
1021
+ }
1022
+ return {
1023
+ fieldType,
1024
+ defaults: (0, import_service_utils.buildDefinedPayload)(defaults)
1025
+ };
1026
+ });
1027
+ }
1028
+ collectRelationNestedFieldPaths(fieldNode) {
1029
+ var _a, _b, _c, _d, _e, _f, _g;
1030
+ 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();
1031
+ if (["SubTableFieldModel", "DisplaySubTableFieldModel"].includes(fieldUse)) {
1032
+ return import_lodash.default.castArray(((_c = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _c.columns) || []).map((item) => {
1033
+ var _a2, _b2, _c2;
1034
+ return (_c2 = (_b2 = (_a2 = item == null ? void 0 : item.stepParams) == null ? void 0 : _a2.fieldSettings) == null ? void 0 : _b2.init) == null ? void 0 : _c2.fieldPath;
1035
+ }).filter(Boolean);
1036
+ }
1037
+ if (fieldUse === "PopupSubTableFieldModel") {
1038
+ return import_lodash.default.castArray(((_d = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _d.subTableColumns) || []).filter((item) => (item == null ? void 0 : item.use) === "TableColumnModel").map((item) => {
1039
+ var _a2, _b2, _c2;
1040
+ return (_c2 = (_b2 = (_a2 = item == null ? void 0 : item.stepParams) == null ? void 0 : _a2.fieldSettings) == null ? void 0 : _b2.init) == null ? void 0 : _c2.fieldPath;
1041
+ }).filter(Boolean);
1042
+ }
1043
+ if (["SubFormFieldModel", "SubFormListFieldModel", "DisplaySubItemFieldModel", "DisplaySubListFieldModel"].includes(
1044
+ fieldUse
1045
+ )) {
1046
+ return import_lodash.default.castArray(((_g = (_f = (_e = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _e.grid) == null ? void 0 : _f.subModels) == null ? void 0 : _g.items) || []).map((item) => {
1047
+ var _a2, _b2, _c2;
1048
+ return (_c2 = (_b2 = (_a2 = item == null ? void 0 : item.stepParams) == null ? void 0 : _a2.fieldSettings) == null ? void 0 : _b2.init) == null ? void 0 : _c2.fieldPath;
1049
+ }).filter(Boolean);
1050
+ }
1051
+ return void 0;
1052
+ }
1053
+ collectRelationSelectorFieldPaths(fieldNode) {
1054
+ var _a, _b, _c, _d, _e, _f;
1055
+ 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();
1056
+ if (fieldUse !== "RecordPickerFieldModel") {
1057
+ return void 0;
1058
+ }
1059
+ 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(
1060
+ (item) => (item == null ? void 0 : item.use) === "TableBlockModel"
1061
+ );
1062
+ return import_lodash.default.castArray(((_f = table == null ? void 0 : table.subModels) == null ? void 0 : _f.columns) || []).map((item) => {
1063
+ var _a2, _b2, _c2;
1064
+ 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;
1065
+ }).filter(Boolean);
1066
+ }
965
1067
  projectCatalogItem(item, expand) {
966
1068
  return (0, import_catalog_smart.projectCatalogItem)(item, expand, {
967
1069
  getEditableDomains: this.getEditableDomains.bind(this),
@@ -1124,7 +1226,7 @@ class FlowSurfacesService {
1124
1226
  if (!POPUP_HOST_DEFAULT_RECORD_CONTEXT_ACTION_USES.has(hostUse)) {
1125
1227
  return false;
1126
1228
  }
1127
- if (hostUse === "CalendarEventViewActionModel") {
1229
+ if (hostUse === "CalendarEventViewActionModel" || hostUse === "KanbanCardViewActionModel") {
1128
1230
  return true;
1129
1231
  }
1130
1232
  return !!(hostContext == null ? void 0 : hostContext.recordActionContainerUse);
@@ -1799,7 +1901,9 @@ class FlowSurfacesService {
1799
1901
  target: targetInput
1800
1902
  });
1801
1903
  const resolved = await this.locator.resolve(writeTarget, options);
1802
- const rawNode = await this.loadResolvedNode(resolved, options.transaction);
1904
+ const rawNode = await this.loadResolvedNode(resolved, options.transaction, {
1905
+ persistCalendarPopupHosts: options.persistCalendarPopupHosts
1906
+ });
1803
1907
  const node = this.stripInternalSurfaceMetaFromNodeTree(import_lodash.default.cloneDeep(rawNode));
1804
1908
  const resolvedTarget = (0, import_resolver.resolveReactionTarget)({
1805
1909
  target: writeTarget,
@@ -1886,11 +1990,10 @@ class FlowSurfacesService {
1886
1990
  }
1887
1991
  async getReactionMeta(values, options = {}) {
1888
1992
  (0, import_payload_shape.validateFlowSurfacePayloadShape)("getReactionMeta", values, "values");
1889
- const { writeTarget, node, resolvedTarget } = await this.resolveReactionRequest(
1890
- "getReactionMeta",
1891
- values == null ? void 0 : values.target,
1892
- options
1893
- );
1993
+ const { writeTarget, node, resolvedTarget } = await this.resolveReactionRequest("getReactionMeta", values == null ? void 0 : values.target, {
1994
+ ...options,
1995
+ persistCalendarPopupHosts: false
1996
+ });
1894
1997
  const context = await this.context(
1895
1998
  {
1896
1999
  target: writeTarget
@@ -2123,7 +2226,11 @@ class FlowSurfacesService {
2123
2226
  const target = this.normalizeGetTarget(input);
2124
2227
  const resolved = await this.locator.resolve(target, options);
2125
2228
  const rawNode = await this.decorateTemplateReadbackTree(
2126
- this.normalizePopupTreeShape(await this.loadResolvedNode(resolved, options.transaction)),
2229
+ this.normalizePopupTreeShape(
2230
+ await this.loadResolvedNode(resolved, options.transaction, {
2231
+ persistCalendarPopupHosts: false
2232
+ })
2233
+ ),
2127
2234
  options.transaction
2128
2235
  );
2129
2236
  const publicNode = this.stripInternalSurfaceMetaFromNodeTree(import_lodash.default.cloneDeep(rawNode));
@@ -2193,7 +2300,11 @@ class FlowSurfacesService {
2193
2300
  normalizeGetTarget: (value) => this.normalizeGetTarget(value),
2194
2301
  resolveLocator: (target, resolveOptions) => this.locator.resolve(target, resolveOptions),
2195
2302
  loadResolvedSurfaceTree: async (resolved, transaction) => this.decorateTemplateReadbackTree(
2196
- this.normalizePopupTreeShape(await this.loadResolvedNode(resolved, transaction)),
2303
+ this.normalizePopupTreeShape(
2304
+ await this.loadResolvedNode(resolved, transaction, {
2305
+ persistCalendarPopupHosts: false
2306
+ })
2307
+ ),
2197
2308
  transaction
2198
2309
  ),
2199
2310
  stripInternalSurfaceMetaFromNodeTree: (node) => this.stripInternalSurfaceMetaFromNodeTree(node),
@@ -2421,9 +2532,11 @@ class FlowSurfacesService {
2421
2532
  disabledReason.startsWith("requires root use compatible") ? "FLOW_SURFACE_TEMPLATE_FIELDS_USE_MISMATCH" : "FLOW_SURFACE_TEMPLATE_FIELDS_RESOURCE_MISMATCH"
2422
2533
  );
2423
2534
  }
2424
- async loadTemplateListTargetContext(target, transaction) {
2535
+ async loadTemplateListTargetContext(target, transaction, options = {}) {
2425
2536
  const resolved = await this.locator.resolve(target, { transaction });
2426
- const node = await this.loadResolvedNode(resolved, transaction);
2537
+ const node = await this.loadResolvedNode(resolved, transaction, {
2538
+ persistCalendarPopupHosts: options.persistCalendarPopupHosts
2539
+ });
2427
2540
  const resourceContext = await this.locator.resolveCollectionContext(node.uid, transaction).catch(() => null);
2428
2541
  const fieldContainer = await this.surfaceContext.resolveFieldContainer(node.uid, transaction).catch(() => null);
2429
2542
  const fieldHostBlock = (fieldContainer == null ? void 0 : fieldContainer.ownerUid) && fieldContainer.ownerUid !== node.uid ? await this.repository.findModelById(fieldContainer.ownerUid, {
@@ -2801,7 +2914,9 @@ class FlowSurfacesService {
2801
2914
  );
2802
2915
  }
2803
2916
  const target = import_lodash.default.isUndefined(values == null ? void 0 : values.target) ? void 0 : this.normalizeWriteTarget("listTemplates", values == null ? void 0 : values.target, values);
2804
- const targetContext = target ? await this.loadTemplateListTargetContext(target, options.transaction) : void 0;
2917
+ const targetContext = target ? await this.loadTemplateListTargetContext(target, options.transaction, {
2918
+ persistCalendarPopupHosts: false
2919
+ }) : void 0;
2805
2920
  const popupActionContext = requestedType === "popup" ? this.resolveTemplateListPopupActionContext({
2806
2921
  targetContext,
2807
2922
  actionType: requestedActionType,
@@ -3220,7 +3335,7 @@ class FlowSurfacesService {
3220
3335
  const name = (0, import_template_service_utils.normalizeRequiredTemplateString)("saveTemplate", values == null ? void 0 : values.name, "name");
3221
3336
  const description = (0, import_template_service_utils.normalizeRequiredTemplateString)("saveTemplate", values == null ? void 0 : values.description, "description");
3222
3337
  const saveMode = (0, import_template_service_utils.normalizeTemplateSaveMode)("saveTemplate", values == null ? void 0 : values.saveMode);
3223
- const target = this.normalizeWriteTarget("saveTemplate", values == null ? void 0 : values.target, values);
3338
+ const target = await this.prepareWriteTarget("saveTemplate", values == null ? void 0 : values.target, values, options);
3224
3339
  const sourceNode = await this.repository.findModelById(target.uid, {
3225
3340
  transaction: options.transaction,
3226
3341
  includeAsyncNode: true
@@ -3453,7 +3568,7 @@ class FlowSurfacesService {
3453
3568
  return duplicatedTree;
3454
3569
  }
3455
3570
  async convertTemplateToCopy(values, options = {}) {
3456
- const target = this.normalizeWriteTarget("convertTemplateToCopy", values == null ? void 0 : values.target, values);
3571
+ const target = await this.prepareWriteTarget("convertTemplateToCopy", values == null ? void 0 : values.target, values, options);
3457
3572
  const node = await this.repository.findModelById(target.uid, {
3458
3573
  transaction: options.transaction,
3459
3574
  includeAsyncNode: true
@@ -3661,7 +3776,7 @@ class FlowSurfacesService {
3661
3776
  async compose(values, options = {}) {
3662
3777
  var _a, _b, _c;
3663
3778
  const popupTemplateAliasSession = options.popupTemplateAliasSession || this.createPopupTemplateAliasSession();
3664
- const target = this.normalizeWriteTarget("compose", values == null ? void 0 : values.target, values);
3779
+ const target = await this.prepareWriteTarget("compose", values == null ? void 0 : values.target, values, options);
3665
3780
  const mode = this.assertComposeMode(values == null ? void 0 : values.mode);
3666
3781
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
3667
3782
  const normalizedBlocks = this.normalizeComposeBlocks(values == null ? void 0 : values.blocks, enabledPackages);
@@ -3763,7 +3878,7 @@ class FlowSurfacesService {
3763
3878
  return result;
3764
3879
  }
3765
3880
  async configure(values, options = {}) {
3766
- const target = this.normalizeWriteTarget("configure", values == null ? void 0 : values.target, values);
3881
+ const target = await this.prepareWriteTarget("configure", values == null ? void 0 : values.target, values, options);
3767
3882
  if (!import_lodash.default.isPlainObject(values.changes) || !Object.keys(values.changes).length) {
3768
3883
  (0, import_errors.throwBadRequest)("flowSurfaces configure requires a non-empty changes object");
3769
3884
  }
@@ -3782,6 +3897,12 @@ class FlowSurfacesService {
3782
3897
  if ((current == null ? void 0 : current.use) === "CalendarBlockModel") {
3783
3898
  return this.configureCalendarBlock(target, current, values.changes, options);
3784
3899
  }
3900
+ if ((current == null ? void 0 : current.use) === "TreeBlockModel") {
3901
+ return this.configureTreeBlock(target, current, values.changes, options);
3902
+ }
3903
+ if ((current == null ? void 0 : current.use) === "KanbanBlockModel") {
3904
+ return this.configureKanbanBlock(target, current, values.changes, options);
3905
+ }
3785
3906
  if (SIMPLE_FORM_BLOCK_USES.has((current == null ? void 0 : current.use) || "")) {
3786
3907
  return this.configureFormBlock(target, current.use, values.changes, options);
3787
3908
  }
@@ -3837,7 +3958,10 @@ class FlowSurfacesService {
3837
3958
  return this.configureFieldNode(target, values.changes, options);
3838
3959
  }
3839
3960
  if (import_node_use_sets.ACTION_BUTTON_USES.has((current == null ? void 0 : current.use) || "")) {
3840
- return this.configureActionNode(target, current.use, values.changes, options);
3961
+ return this.configureActionNode(target, current.use, values.changes, {
3962
+ ...options,
3963
+ current
3964
+ });
3841
3965
  }
3842
3966
  (0, import_errors.throwBadRequest)(`flowSurfaces configure does not support configureOptions on '${(current == null ? void 0 : current.use) || resolved.uid}'`);
3843
3967
  }
@@ -4628,7 +4752,7 @@ class FlowSurfacesService {
4628
4752
  "FLOW_SURFACE_TEMPLATE_REFERENCE_SETTINGS_UNSUPPORTED"
4629
4753
  );
4630
4754
  }
4631
- const target = this.normalizeWriteTarget("addBlock", values == null ? void 0 : values.target, values);
4755
+ const target = await this.prepareWriteTarget("addBlock", values == null ? void 0 : values.target, values, options);
4632
4756
  await this.assertBlockTemplateCompatibility("addBlock", target, template, options.transaction);
4633
4757
  const { parentUid, subKey, subType, popupSurface } = await this.surfaceContext.resolveBlockParent(
4634
4758
  target,
@@ -4695,7 +4819,7 @@ class FlowSurfacesService {
4695
4819
  transaction: options.transaction,
4696
4820
  expectedType: "block"
4697
4821
  });
4698
- const target = this.normalizeWriteTarget("addField", values == null ? void 0 : values.target, values);
4822
+ const target = await this.prepareWriteTarget("addField", values == null ? void 0 : values.target, values, options);
4699
4823
  const resolvedTarget = await this.locator.resolve(target, options);
4700
4824
  const container = await this.surfaceContext.resolveFieldContainer(resolvedTarget.uid, options.transaction);
4701
4825
  const result = await this.applyTemplateFieldsToBlock(
@@ -4773,7 +4897,7 @@ class FlowSurfacesService {
4773
4897
  };
4774
4898
  }
4775
4899
  async addBlock(values, options = {}) {
4776
- var _a, _b, _c, _d, _e;
4900
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
4777
4901
  const templateRef = import_lodash.default.isUndefined(values == null ? void 0 : values.template) ? void 0 : this.normalizeFlowTemplateReference("addBlock", values.template, {
4778
4902
  allowUsage: true,
4779
4903
  expectedType: "block"
@@ -4794,7 +4918,7 @@ class FlowSurfacesService {
4794
4918
  await this.persistCreatedKeysForAction("addBlock", values, result2, options.transaction);
4795
4919
  return result2;
4796
4920
  }
4797
- const target = this.normalizeWriteTarget("addBlock", values == null ? void 0 : values.target, values);
4921
+ const target = await this.prepareWriteTarget("addBlock", values == null ? void 0 : values.target, values, options);
4798
4922
  (0, import_service_utils.ensureNoRawDirectAddKeys)("addBlock", values, ["props", "decoratorProps", "stepParams", "flowRegistry"]);
4799
4923
  const inlineSettings = this.normalizeInlineSettings("addBlock", values.settings);
4800
4924
  const semanticResource = this.normalizeResourceInput(values.resource);
@@ -4803,6 +4927,7 @@ class FlowSurfacesService {
4803
4927
  (0, import_errors.throwBadRequest)("flowSurfaces addBlock does not allow resource and resourceInit at the same time");
4804
4928
  }
4805
4929
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
4930
+ const hasInlineFields = Object.prototype.hasOwnProperty.call(values || {}, "fields") || Object.prototype.hasOwnProperty.call(values || {}, "fieldsLayout");
4806
4931
  let resolvedTarget = await this.locator.resolve(target, options);
4807
4932
  let targetNode = await this.loadResolvedNode(resolvedTarget, options.transaction);
4808
4933
  const targetOpenView = this.resolvePopupHostOpenView(targetNode);
@@ -4837,6 +4962,16 @@ class FlowSurfacesService {
4837
4962
  requireCreateSupported: true
4838
4963
  }
4839
4964
  );
4965
+ const inlineFields = hasInlineFields ? this.normalizeComposeBlock(
4966
+ {
4967
+ 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",
4968
+ type: catalogItem.key || values.type,
4969
+ fields: values.fields,
4970
+ fieldsLayout: values.fieldsLayout
4971
+ },
4972
+ 0,
4973
+ enabledPackages
4974
+ ) : null;
4840
4975
  const resolvedResourceInit = await this.resolvePopupCollectionBlockResourceInit({
4841
4976
  actionName: "addBlock",
4842
4977
  blockUse: catalogItem.use,
@@ -4850,7 +4985,7 @@ class FlowSurfacesService {
4850
4985
  resourceInit: resolvedResourceInit,
4851
4986
  resourceField: rawResourceInit ? "resourceInit" : (semanticResource == null ? void 0 : semanticResource.kind) === "raw" ? "resource" : void 0
4852
4987
  });
4853
- const effectiveResourceInit = catalogItem.use === "CalendarBlockModel" && resolvedResourceInit.collectionName && !resolvedResourceInit.dataSourceKey ? {
4988
+ const effectiveResourceInit = (catalogItem.use === "CalendarBlockModel" || catalogItem.use === "KanbanBlockModel") && resolvedResourceInit.collectionName && !resolvedResourceInit.dataSourceKey ? {
4854
4989
  ...resolvedResourceInit,
4855
4990
  dataSourceKey: "main"
4856
4991
  } : resolvedResourceInit;
@@ -4858,6 +4993,10 @@ class FlowSurfacesService {
4858
4993
  actionName: "addBlock",
4859
4994
  resourceInit: effectiveResourceInit,
4860
4995
  props: values.props
4996
+ }) : catalogItem.use === "KanbanBlockModel" ? this.buildKanbanInitialBlockProps({
4997
+ actionName: "addBlock",
4998
+ resourceInit: effectiveResourceInit,
4999
+ props: values.props
4861
5000
  }) : values.props;
4862
5001
  const initialGrid = options.deferAutoLayout ? null : await this.repository.findModelById(parentUid, {
4863
5002
  transaction: options.transaction,
@@ -4906,6 +5045,73 @@ class FlowSurfacesService {
4906
5045
  } : {}
4907
5046
  };
4908
5047
  await this.applyInlineNodeSettings("addBlock", created, inlineSettings, options);
5048
+ if ((_f = inlineFields == null ? void 0 : inlineFields.fields) == null ? void 0 : _f.length) {
5049
+ const fieldTargetUid = this.resolveComposeFieldContainerUid(inlineFields, result);
5050
+ const createdByKey = {};
5051
+ for (const fieldSpec of inlineFields.fields) {
5052
+ const createdField = await this.addField(
5053
+ {
5054
+ target: {
5055
+ uid: fieldTargetUid
5056
+ },
5057
+ ...fieldSpec.key ? { key: fieldSpec.key } : {},
5058
+ ...fieldSpec.fieldPath ? { fieldPath: fieldSpec.fieldPath } : {},
5059
+ ...fieldSpec.associationPathName ? { associationPathName: fieldSpec.associationPathName } : {},
5060
+ ...fieldSpec.renderer ? { renderer: fieldSpec.renderer } : {},
5061
+ ...fieldSpec.type ? { type: fieldSpec.type } : {},
5062
+ ...fieldSpec.fieldType ? { fieldType: fieldSpec.fieldType } : {},
5063
+ ...!import_lodash.default.isUndefined(fieldSpec.fields) ? { fields: fieldSpec.fields } : {},
5064
+ ...!import_lodash.default.isUndefined(fieldSpec.selectorFields) ? { selectorFields: fieldSpec.selectorFields } : {},
5065
+ ...fieldSpec.titleField ? { titleField: fieldSpec.titleField } : {},
5066
+ ...fieldSpec.openMode ? { openMode: fieldSpec.openMode } : {},
5067
+ ...fieldSpec.popupSize ? { popupSize: fieldSpec.popupSize } : {},
5068
+ ...!import_lodash.default.isUndefined(fieldSpec.pageSize) ? { pageSize: fieldSpec.pageSize } : {},
5069
+ ...!import_lodash.default.isUndefined(fieldSpec.showIndex) ? { showIndex: fieldSpec.showIndex } : {},
5070
+ ...fieldSpec.popup ? { popup: fieldSpec.popup } : {},
5071
+ ...fieldSpec.__autoPopupForRelationField ? { __autoPopupForRelationField: true } : {},
5072
+ ...fieldSpec[import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY] ? {
5073
+ [import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY]: fieldSpec[import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY]
5074
+ } : {}
5075
+ },
5076
+ {
5077
+ transaction: options.transaction,
5078
+ enabledPackages
5079
+ }
5080
+ );
5081
+ if (fieldSpec.settings && Object.keys(fieldSpec.settings).length) {
5082
+ await this.applyInlineFieldSettings("addBlock field", createdField, fieldSpec.settings, {
5083
+ transaction: options.transaction
5084
+ });
5085
+ }
5086
+ const layoutUid = createdField.wrapperUid || createdField.uid;
5087
+ if (layoutUid && fieldSpec.key) {
5088
+ createdByKey[fieldSpec.key] = { uid: layoutUid };
5089
+ }
5090
+ }
5091
+ if (inlineFields.fieldsLayout && Object.keys(createdByKey).length) {
5092
+ const layoutHost = await this.repository.findModelById(created, {
5093
+ transaction: options.transaction,
5094
+ includeAsyncNode: true
5095
+ });
5096
+ const layoutItems = import_lodash.default.castArray(
5097
+ ((_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) || []
5098
+ );
5099
+ const layoutPayload = this.buildComposeLayoutPayload({
5100
+ layout: inlineFields.fieldsLayout,
5101
+ createdByKey,
5102
+ finalItems: layoutItems
5103
+ });
5104
+ await this.setLayout(
5105
+ {
5106
+ target: {
5107
+ uid: created
5108
+ },
5109
+ ...layoutPayload
5110
+ },
5111
+ options
5112
+ );
5113
+ }
5114
+ }
4909
5115
  if (!options.skipDefaultBlockActions) {
4910
5116
  await this.applyDefaultActionsForCreatedBlock(
4911
5117
  {
@@ -4951,7 +5157,9 @@ class FlowSurfacesService {
4951
5157
  await this.persistCreatedKeysForAction("addField", values, result2, options.transaction);
4952
5158
  return result2;
4953
5159
  }
4954
- const target = this.normalizeWriteTarget("addField", values == null ? void 0 : values.target, values);
5160
+ const target = await this.prepareWriteTarget("addField", values == null ? void 0 : values.target, values, options);
5161
+ (0, import_field_type_resolver.assertNoInternalFieldKeys)(values, "flowSurfaces addField");
5162
+ (0, import_field_type_resolver.assertNoInternalFieldKeys)(values == null ? void 0 : values.settings, "flowSurfaces addField.settings");
4955
5163
  (0, import_service_utils.ensureNoRawDirectAddKeys)("addField", values, [
4956
5164
  "wrapperProps",
4957
5165
  "fieldProps",
@@ -4968,6 +5176,8 @@ class FlowSurfacesService {
4968
5176
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
4969
5177
  const isFilterFormItem = container.wrapperUse === "FilterFormItemModel";
4970
5178
  const isApprovalFormTarget = (0, import_approval.isApprovalFormContainerUse)(container.ownerUse);
5179
+ const requestedLegacyFieldUse = (0, import_service_utils.resolveRequestedFieldUseAlias)(values);
5180
+ let requestedFieldUse = (0, import_service_utils.resolveRequestedFieldUse)(values);
4971
5181
  const requestedStandaloneType = typeof values.type === "string" && values.type.trim().length ? values.type.trim() : void 0;
4972
5182
  const fieldCapability = (0, import_catalog.resolveSupportedFieldCapability)({
4973
5183
  containerUse: container.ownerUse,
@@ -4978,6 +5188,9 @@ class FlowSurfacesService {
4978
5188
  enabledPackages
4979
5189
  });
4980
5190
  if (fieldCapability.standaloneUse) {
5191
+ if ((0, import_service_utils.hasOwnDefined)(values, "fieldType")) {
5192
+ (0, import_errors.throwBadRequest)("flowSurfaces fieldType is only supported for relation fields");
5193
+ }
4981
5194
  if (inlinePopup) {
4982
5195
  (0, import_errors.throwBadRequest)(`flowSurfaces addField type '${values.type}' does not support popup`);
4983
5196
  }
@@ -5083,6 +5296,32 @@ class FlowSurfacesService {
5083
5296
  associationPathName: resolvedField.associationPathName,
5084
5297
  field: resolvedField.field
5085
5298
  });
5299
+ const relationFieldTypeResolution = (0, import_field_type_resolver.resolveRelationFieldType)({
5300
+ fieldType: values.fieldType,
5301
+ containerUse: container.ownerUse,
5302
+ field: resolvedField.field,
5303
+ dataSourceKey: resolvedField.dataSourceKey,
5304
+ getCollection: (dataSourceKey, collectionName) => this.getCollection(dataSourceKey, collectionName),
5305
+ fields: values.fields,
5306
+ selectorFields: values.selectorFields,
5307
+ titleField: values.titleField,
5308
+ openMode: values.openMode,
5309
+ popupSize: values.popupSize,
5310
+ pageSize: values.pageSize,
5311
+ showIndex: values.showIndex,
5312
+ context: "addField"
5313
+ });
5314
+ if (relationFieldTypeResolution) {
5315
+ if (values.renderer) {
5316
+ (0, import_errors.throwBadRequest)(`flowSurfaces addField fieldType cannot be combined with renderer`);
5317
+ }
5318
+ if (requestedLegacyFieldUse && requestedLegacyFieldUse !== relationFieldTypeResolution.fieldUse) {
5319
+ (0, import_errors.throwBadRequest)(
5320
+ `flowSurfaces fieldUse '${requestedLegacyFieldUse}' does not match fieldType '${relationFieldTypeResolution.fieldType}'`
5321
+ );
5322
+ }
5323
+ requestedFieldUse = relationFieldTypeResolution.fieldUse;
5324
+ }
5086
5325
  const filterFormInit = isFilterFormItem ? {
5087
5326
  filterField: (0, import_service_helpers.buildFilterFieldMeta)(resolvedField.field),
5088
5327
  ...(selectedFilterTarget == null ? void 0 : selectedFilterTarget.ownerUid) ? { defaultTargetUid: selectedFilterTarget.ownerUid } : {}
@@ -5090,25 +5329,29 @@ class FlowSurfacesService {
5090
5329
  let capabilityField = preferredCapabilityField;
5091
5330
  let boundFieldCapability;
5092
5331
  if ((fieldMenuCandidate == null ? void 0 : fieldMenuCandidate.explicitWrapperUse) && (fieldMenuCandidate == null ? void 0 : fieldMenuCandidate.explicitFieldUse) && !values.renderer) {
5093
- if ((0, import_service_utils.hasOwnDefined)(values, "fieldUse") && values.fieldUse !== fieldMenuCandidate.explicitFieldUse) {
5332
+ if (requestedLegacyFieldUse && requestedLegacyFieldUse !== fieldMenuCandidate.explicitFieldUse) {
5094
5333
  (0, import_errors.throwBadRequest)(
5095
- `flowSurfaces fieldUse '${values.fieldUse}' does not match inferred fieldUse '${fieldMenuCandidate.explicitFieldUse}' under '${container.ownerUse}'`
5334
+ `flowSurfaces fieldUse '${requestedLegacyFieldUse}' does not match inferred fieldUse '${fieldMenuCandidate.explicitFieldUse}' under '${container.ownerUse}'`
5096
5335
  );
5097
5336
  }
5098
- boundFieldCapability = {
5099
- wrapperUse: fieldMenuCandidate.explicitWrapperUse,
5100
- fieldUse: fieldMenuCandidate.explicitFieldUse,
5101
- inferredFieldUse: fieldMenuCandidate.explicitFieldUse,
5102
- standaloneUse: void 0,
5103
- renderer: void 0
5104
- };
5105
- capabilityField = resolvedField.field;
5106
- } else {
5337
+ if (!relationFieldTypeResolution) {
5338
+ boundFieldCapability = {
5339
+ wrapperUse: fieldMenuCandidate.explicitWrapperUse,
5340
+ fieldUse: fieldMenuCandidate.explicitFieldUse,
5341
+ inferredFieldUse: fieldMenuCandidate.explicitFieldUse,
5342
+ standaloneUse: void 0,
5343
+ renderer: void 0
5344
+ };
5345
+ capabilityField = resolvedField.field;
5346
+ }
5347
+ }
5348
+ if (!boundFieldCapability) {
5107
5349
  try {
5108
5350
  boundFieldCapability = (0, import_catalog.resolveSupportedFieldCapability)({
5109
5351
  containerUse: container.ownerUse,
5110
5352
  field: capabilityField,
5111
- requestedFieldUse: values.fieldUse,
5353
+ requestedFieldUse,
5354
+ requestedFieldUseMode: relationFieldTypeResolution ? "fieldType" : "fieldUse",
5112
5355
  requestedWrapperUse: container.wrapperUse,
5113
5356
  requestedRenderer: values.renderer,
5114
5357
  enabledPackages,
@@ -5116,12 +5359,13 @@ class FlowSurfacesService {
5116
5359
  getCollection: (dataSourceKey, collectionName) => this.getCollection(dataSourceKey, collectionName)
5117
5360
  });
5118
5361
  } catch (error) {
5119
- if ((0, import_service_utils.hasOwnDefined)(values, "fieldUse") && capabilityField !== resolvedField.field && error instanceof import_errors.FlowSurfaceBadRequestError) {
5362
+ if (requestedFieldUse && capabilityField !== resolvedField.field && error instanceof import_errors.FlowSurfaceBadRequestError) {
5120
5363
  capabilityField = resolvedField.field;
5121
5364
  boundFieldCapability = (0, import_catalog.resolveSupportedFieldCapability)({
5122
5365
  containerUse: container.ownerUse,
5123
5366
  field: capabilityField,
5124
- requestedFieldUse: values.fieldUse,
5367
+ requestedFieldUse,
5368
+ requestedFieldUseMode: relationFieldTypeResolution ? "fieldType" : "fieldUse",
5125
5369
  requestedWrapperUse: container.wrapperUse,
5126
5370
  requestedRenderer: values.renderer,
5127
5371
  enabledPackages,
@@ -5155,9 +5399,17 @@ class FlowSurfacesService {
5155
5399
  boundFieldCapability.fieldUse,
5156
5400
  capabilityField
5157
5401
  );
5158
- const defaultTitleField = titleFieldSyncDecision.titleField ?? normalizedFieldBinding.defaultTitleField ?? (fieldMenuCandidate == null ? void 0 : fieldMenuCandidate.defaultTitleField);
5402
+ const defaultTitleField = (relationFieldTypeResolution == null ? void 0 : relationFieldTypeResolution.titleField) ?? titleFieldSyncDecision.titleField ?? normalizedFieldBinding.defaultTitleField ?? (fieldMenuCandidate == null ? void 0 : fieldMenuCandidate.defaultTitleField);
5159
5403
  const wrapperShouldPersistTitleField = !import_lodash.default.isUndefined(defaultTitleField) && TITLE_FIELD_SUPPORTED_WRAPPER_USES.has(boundFieldCapability.wrapperUse || "");
5160
- const fieldShouldPersistTitleField = !import_lodash.default.isUndefined(defaultTitleField);
5404
+ const fieldShouldPersistTitleField = !import_lodash.default.isUndefined(defaultTitleField) && this.supportsFieldTitleFieldProp(boundFieldCapability.fieldUse);
5405
+ const normalizedDefaultFieldProps = this.normalizeFieldPropsForUse(
5406
+ boundFieldCapability.fieldUse,
5407
+ defaultFieldState.fieldProps || {}
5408
+ );
5409
+ const normalizedInlineFieldProps = this.normalizeFieldPropsForUse(
5410
+ boundFieldCapability.fieldUse,
5411
+ values.fieldProps || {}
5412
+ );
5161
5413
  const tree = (0, import_builder.buildFieldTree)({
5162
5414
  wrapperUse: boundFieldCapability.wrapperUse,
5163
5415
  fieldUse: boundFieldCapability.fieldUse,
@@ -5174,9 +5426,9 @@ class FlowSurfacesService {
5174
5426
  ),
5175
5427
  fieldProps: import_lodash.default.merge(
5176
5428
  {},
5177
- defaultFieldState.fieldProps || {},
5429
+ normalizedDefaultFieldProps,
5178
5430
  fieldShouldPersistTitleField ? { titleField: defaultTitleField } : {},
5179
- values.fieldProps || {}
5431
+ normalizedInlineFieldProps
5180
5432
  )
5181
5433
  });
5182
5434
  this.contractGuard.validateNodeTreeAgainstContract(tree.model);
@@ -5215,6 +5467,21 @@ class FlowSurfacesService {
5215
5467
  associationPathName: normalizedFieldBinding.associationPathName,
5216
5468
  fieldPath: normalizedFieldBinding.fieldPath
5217
5469
  };
5470
+ if (relationFieldTypeResolution) {
5471
+ await this.applyResolvedRelationFieldType({
5472
+ fieldUid: tree.innerUid,
5473
+ fieldUse: boundFieldCapability.fieldUse,
5474
+ targetCollection: relationFieldTypeResolution.targetCollection,
5475
+ fields: relationFieldTypeResolution.fields,
5476
+ selectorFields: relationFieldTypeResolution.selectorFields,
5477
+ titleField: relationFieldTypeResolution.titleField,
5478
+ openMode: relationFieldTypeResolution.openMode,
5479
+ popupSize: relationFieldTypeResolution.popupSize,
5480
+ pageSize: relationFieldTypeResolution.pageSize,
5481
+ showIndex: relationFieldTypeResolution.showIndex,
5482
+ transaction: options.transaction
5483
+ });
5484
+ }
5218
5485
  await this.applyInlineFieldSettings("addField", result, inlineSettings, options);
5219
5486
  await this.applyInlineFieldPopup("addField", result, inlinePopup, {
5220
5487
  ...options,
@@ -5224,7 +5491,7 @@ class FlowSurfacesService {
5224
5491
  return result;
5225
5492
  }
5226
5493
  async addAction(values, options = {}) {
5227
- const target = this.normalizeWriteTarget("addAction", values == null ? void 0 : values.target, values);
5494
+ const target = await this.prepareWriteTarget("addAction", values == null ? void 0 : values.target, values, options);
5228
5495
  (0, import_service_utils.ensureNoDirectActionScopeKey)("addAction", values);
5229
5496
  (0, import_service_utils.ensureNoRawDirectAddKeys)("addAction", values, ["props", "decoratorProps", "stepParams", "flowRegistry"]);
5230
5497
  const inlineSettings = this.normalizeInlineSettings("addAction", values.settings);
@@ -5321,7 +5588,7 @@ class FlowSurfacesService {
5321
5588
  return result;
5322
5589
  }
5323
5590
  async addRecordAction(values, options = {}) {
5324
- const target = this.normalizeWriteTarget("addRecordAction", values == null ? void 0 : values.target, values);
5591
+ const target = await this.prepareWriteTarget("addRecordAction", values == null ? void 0 : values.target, values, options);
5325
5592
  (0, import_service_utils.ensureNoDirectActionScopeKey)("addRecordAction", values);
5326
5593
  (0, import_service_utils.ensureNoRawDirectAddKeys)("addRecordAction", values, ["props", "decoratorProps", "stepParams", "flowRegistry"]);
5327
5594
  const inlineSettings = this.normalizeInlineSettings("addRecordAction", values.settings);
@@ -7551,7 +7818,7 @@ class FlowSurfacesService {
7551
7818
  async updateSettings(values, options = {}) {
7552
7819
  var _a, _b;
7553
7820
  (0, import_payload_shape.validateFlowSurfacePayloadShape)("updateSettings", values, "values");
7554
- const writeTarget = this.normalizeWriteTarget("updateSettings", values == null ? void 0 : values.target, values);
7821
+ const writeTarget = await this.prepareWriteTarget("updateSettings", values == null ? void 0 : values.target, values, options);
7555
7822
  const target = await this.locator.resolve(writeTarget, options);
7556
7823
  const current = await this.loadResolvedNode(target, options.transaction);
7557
7824
  const normalizedValues = import_lodash.default.cloneDeep(values || {});
@@ -7611,6 +7878,7 @@ class FlowSurfacesService {
7611
7878
  };
7612
7879
  const shouldValidateFlowRegistry = !import_lodash.default.isUndefined(nextPayload.flowRegistry) || !import_lodash.default.isUndefined(nextPayload.stepParams);
7613
7880
  this.validateCalendarBlockState("updateSettings", effectiveNode);
7881
+ this.validateKanbanBlockState("updateSettings", effectiveNode);
7614
7882
  if (shouldValidateFlowRegistry && import_lodash.default.isPlainObject(effectiveNode.flowRegistry) && Object.keys(effectiveNode.flowRegistry).length) {
7615
7883
  this.contractGuard.validateFlowRegistry(effectiveNode, effectiveNode.flowRegistry);
7616
7884
  }
@@ -7642,6 +7910,9 @@ class FlowSurfacesService {
7642
7910
  if (current.use === "CalendarBlockModel") {
7643
7911
  await this.ensureCalendarBlockPopupHosts(effectiveNode, options.transaction);
7644
7912
  }
7913
+ if (current.use === "KanbanBlockModel") {
7914
+ await this.ensureKanbanBlockPopupHosts(effectiveNode, options.transaction);
7915
+ }
7645
7916
  await this.syncFlowTemplateUsagesForNodeTree(current.uid, options.transaction);
7646
7917
  if (import_approval.APPROVAL_SINGLETON_ACTION_USES.has(current.use || "")) {
7647
7918
  await this.syncApprovalRuntimeConfigForNode(current.uid, options.transaction);
@@ -8110,7 +8381,7 @@ class FlowSurfacesService {
8110
8381
  );
8111
8382
  }
8112
8383
  async setEventFlows(values, options = {}) {
8113
- const writeTarget = this.normalizeWriteTarget("setEventFlows", values == null ? void 0 : values.target, values);
8384
+ const writeTarget = await this.prepareWriteTarget("setEventFlows", values == null ? void 0 : values.target, values, options);
8114
8385
  const target = await this.locator.resolve(writeTarget, options);
8115
8386
  const current = await this.loadResolvedNode(target, options.transaction);
8116
8387
  const contract = (0, import_catalog.getNodeContract)(current == null ? void 0 : current.use);
@@ -8148,7 +8419,7 @@ class FlowSurfacesService {
8148
8419
  }
8149
8420
  async setLayout(values, options = {}) {
8150
8421
  var _a, _b;
8151
- const target = this.normalizeWriteTarget("setLayout", values == null ? void 0 : values.target, values);
8422
+ const target = await this.prepareWriteTarget("setLayout", values == null ? void 0 : values.target, values, options);
8152
8423
  const resolved = await this.locator.resolve(target, options);
8153
8424
  const grid = await this.surfaceContext.resolveGridNode(resolved.uid, options.transaction);
8154
8425
  const contract = (0, import_catalog.getNodeContract)(grid == null ? void 0 : grid.use);
@@ -8264,7 +8535,7 @@ class FlowSurfacesService {
8264
8535
  async apply(values, options = {}) {
8265
8536
  this.assertApplyMode(values.mode);
8266
8537
  (0, import_payload_shape.validateFlowSurfacePayloadShape)("apply", values == null ? void 0 : values.spec, "spec");
8267
- const target = this.normalizeWriteTarget("apply", values == null ? void 0 : values.target, values);
8538
+ const target = await this.prepareWriteTarget("apply", values == null ? void 0 : values.target, values, options);
8268
8539
  const spec = values.spec;
8269
8540
  const readback = await this.get(target, options);
8270
8541
  const compiled = (0, import_compiler.compileApplySpec)(target, readback.tree, spec);
@@ -8412,6 +8683,72 @@ class FlowSurfacesService {
8412
8683
  }
8413
8684
  return { uid: uid2 };
8414
8685
  }
8686
+ parseCalendarPopupActionTargetUid(uid2) {
8687
+ const normalizedUid = String(uid2 || "").trim();
8688
+ if (!normalizedUid) {
8689
+ return null;
8690
+ }
8691
+ for (const actionKey of CALENDAR_POPUP_ACTION_KEYS) {
8692
+ const suffix = `-${actionKey}`;
8693
+ if (normalizedUid.endsWith(suffix) && normalizedUid.length > suffix.length) {
8694
+ return {
8695
+ calendarUid: normalizedUid.slice(0, -suffix.length),
8696
+ actionKey
8697
+ };
8698
+ }
8699
+ }
8700
+ return null;
8701
+ }
8702
+ parseKanbanPopupActionTargetUid(uid2) {
8703
+ const normalizedUid = String(uid2 || "").trim();
8704
+ if (!normalizedUid) {
8705
+ return null;
8706
+ }
8707
+ for (const actionKey of KANBAN_POPUP_ACTION_KEYS) {
8708
+ const suffix = KANBAN_POPUP_ACTION_UID_SUFFIX_BY_KEY[actionKey];
8709
+ if (normalizedUid.endsWith(suffix) && normalizedUid.length > suffix.length) {
8710
+ return {
8711
+ kanbanUid: normalizedUid.slice(0, -suffix.length),
8712
+ actionKey
8713
+ };
8714
+ }
8715
+ }
8716
+ return null;
8717
+ }
8718
+ async prepareWriteTarget(actionName, target, values, options = {}) {
8719
+ const writeTarget = this.normalizeWriteTarget(actionName, target, values);
8720
+ const parsedCalendarPopupTarget = this.parseCalendarPopupActionTargetUid(writeTarget.uid);
8721
+ const parsedKanbanPopupTarget = this.parseKanbanPopupActionTargetUid(writeTarget.uid);
8722
+ if (!parsedCalendarPopupTarget && !parsedKanbanPopupTarget) {
8723
+ return writeTarget;
8724
+ }
8725
+ const persistedTarget = await this.repository.findModelById(writeTarget.uid, {
8726
+ transaction: options.transaction,
8727
+ includeAsyncNode: true
8728
+ });
8729
+ if (persistedTarget == null ? void 0 : persistedTarget.uid) {
8730
+ return writeTarget;
8731
+ }
8732
+ if (parsedCalendarPopupTarget) {
8733
+ const calendarNode = await this.repository.findModelById(parsedCalendarPopupTarget.calendarUid, {
8734
+ transaction: options.transaction,
8735
+ includeAsyncNode: true
8736
+ }).catch(() => null);
8737
+ if ((calendarNode == null ? void 0 : calendarNode.use) === "CalendarBlockModel") {
8738
+ await this.ensureCalendarBlockPopupHosts(calendarNode, options.transaction);
8739
+ }
8740
+ }
8741
+ if (parsedKanbanPopupTarget) {
8742
+ const kanbanNode = await this.repository.findModelById(parsedKanbanPopupTarget.kanbanUid, {
8743
+ transaction: options.transaction,
8744
+ includeAsyncNode: true
8745
+ }).catch(() => null);
8746
+ if ((kanbanNode == null ? void 0 : kanbanNode.use) === "KanbanBlockModel") {
8747
+ await this.ensureKanbanBlockPopupHosts(kanbanNode, options.transaction);
8748
+ }
8749
+ }
8750
+ return writeTarget;
8751
+ }
8415
8752
  normalizeRootUidValue(actionName, values) {
8416
8753
  if (import_lodash.default.isPlainObject(values == null ? void 0 : values.target)) {
8417
8754
  (0, import_errors.throwBadRequest)(
@@ -8914,6 +9251,11 @@ class FlowSurfacesService {
8914
9251
  subType: "array"
8915
9252
  };
8916
9253
  }
9254
+ if (use === "KanbanBlockModel") {
9255
+ (0, import_errors.throwBadRequest)(
9256
+ `flowSurfaces addRecordAction target '${use}' is not supported; kanban record actions are not exposed in the public API v1`
9257
+ );
9258
+ }
8917
9259
  if (use === "TableActionsColumnModel") {
8918
9260
  (0, import_errors.throwBadRequest)(
8919
9261
  `flowSurfaces addRecordAction target '${use}' is an internal record action container; pass the owning table block uid instead`
@@ -9260,6 +9602,7 @@ class FlowSurfacesService {
9260
9602
  );
9261
9603
  const hasFields = Object.prototype.hasOwnProperty.call(input, "fields");
9262
9604
  const hasFieldGroups = Object.prototype.hasOwnProperty.call(input, "fieldGroups");
9605
+ const hasActions = Object.prototype.hasOwnProperty.call(input, "actions");
9263
9606
  const hasRecordActions = Object.prototype.hasOwnProperty.call(input, "recordActions");
9264
9607
  if (type === "calendar") {
9265
9608
  if (hasFields) {
@@ -9278,6 +9621,40 @@ class FlowSurfacesService {
9278
9621
  );
9279
9622
  }
9280
9623
  }
9624
+ if (type === "kanban") {
9625
+ if (hasFieldGroups) {
9626
+ (0, import_errors.throwBadRequest)(
9627
+ `flowSurfaces compose block #${index + 1} kanban does not support fieldGroups[] on the main block; add card fields directly under fields[] instead`
9628
+ );
9629
+ }
9630
+ if (hasRecordActions) {
9631
+ (0, import_errors.throwBadRequest)(
9632
+ `flowSurfaces compose block #${index + 1} kanban does not support recordActions[] on the main block; configure block actions only in v1`
9633
+ );
9634
+ }
9635
+ if (Object.prototype.hasOwnProperty.call(input, "fieldsLayout")) {
9636
+ (0, import_errors.throwBadRequest)(
9637
+ `flowSurfaces compose block #${index + 1} kanban does not support fieldsLayout on the main block`
9638
+ );
9639
+ }
9640
+ }
9641
+ if (type === "tree") {
9642
+ if (hasFields) {
9643
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support fields[]`);
9644
+ }
9645
+ if (hasFieldGroups) {
9646
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support fieldGroups[]`);
9647
+ }
9648
+ if (hasActions) {
9649
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support actions[]`);
9650
+ }
9651
+ if (hasRecordActions) {
9652
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support recordActions[]`);
9653
+ }
9654
+ if (Object.prototype.hasOwnProperty.call(input, "fieldsLayout")) {
9655
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} tree does not support fieldsLayout`);
9656
+ }
9657
+ }
9281
9658
  if (hasFields && hasFieldGroups) {
9282
9659
  (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} cannot mix fields with fieldGroups`);
9283
9660
  }
@@ -9349,7 +9726,7 @@ class FlowSurfacesService {
9349
9726
  return blockResult.uid;
9350
9727
  }
9351
9728
  resolveComposeFieldContainerUid(blockSpec, blockResult) {
9352
- if (LIST_LIKE_COMPOSE_BLOCK_TYPES.has(blockSpec.type)) {
9729
+ if (CARD_FIELD_COMPOSE_BLOCK_TYPES.has(blockSpec.type)) {
9353
9730
  return blockResult.itemUid || blockResult.uid;
9354
9731
  }
9355
9732
  return blockResult.uid;
@@ -9361,7 +9738,7 @@ class FlowSurfacesService {
9361
9738
  if (blockSpec.type === "details") {
9362
9739
  return blockResult.uid;
9363
9740
  }
9364
- if (!LIST_LIKE_COMPOSE_BLOCK_TYPES.has(blockSpec.type)) {
9741
+ if (!RECORD_ACTION_COMPOSE_BLOCK_TYPES.has(blockSpec.type)) {
9365
9742
  (0, import_errors.throwBadRequest)(
9366
9743
  `flowSurfaces compose recordActions only support 'table', 'details', 'list' or 'gridCard' blocks`
9367
9744
  );
@@ -9721,6 +10098,16 @@ class FlowSurfacesService {
9721
10098
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("CalendarBlockModel");
9722
10099
  const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
9723
10100
  (0, import_service_utils.assertSupportedSimpleChanges)("calendar", changes, allowedKeys);
10101
+ this.validateCalendarSettingValues("configure", {
10102
+ defaultView: changes.defaultView,
10103
+ quickCreateEvent: changes.quickCreateEvent,
10104
+ showLunar: changes.showLunar,
10105
+ weekStart: changes.weekStart
10106
+ });
10107
+ const defaultView = (0, import_service_utils.hasOwnDefined)(changes, "defaultView") ? String(changes.defaultView).trim() : void 0;
10108
+ const quickCreateEvent = (0, import_service_utils.hasOwnDefined)(changes, "quickCreateEvent") ? changes.quickCreateEvent : void 0;
10109
+ const showLunar = (0, import_service_utils.hasOwnDefined)(changes, "showLunar") ? changes.showLunar : void 0;
10110
+ const weekStart = (0, import_service_utils.hasOwnDefined)(changes, "weekStart") ? changes.weekStart : void 0;
9724
10111
  const currentResourceInit = this.getCalendarBlockResourceInit(current);
9725
10112
  const nextResourceInit = changes.resource ? (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource) : currentResourceInit;
9726
10113
  if (nextResourceInit.collectionName && !nextResourceInit.dataSourceKey) {
@@ -9755,10 +10142,10 @@ class FlowSurfacesService {
9755
10142
  target,
9756
10143
  props: (0, import_service_utils.buildDefinedPayload)({
9757
10144
  fieldNames,
9758
- defaultView: changes.defaultView,
9759
- enableQuickCreateEvent: changes.quickCreateEvent,
9760
- showLunar: changes.showLunar,
9761
- weekStart: changes.weekStart,
10145
+ defaultView,
10146
+ enableQuickCreateEvent: quickCreateEvent,
10147
+ showLunar,
10148
+ weekStart,
9762
10149
  quickCreatePopupSettings,
9763
10150
  eventPopupSettings
9764
10151
  }),
@@ -9790,10 +10177,10 @@ class FlowSurfacesService {
9790
10177
  ...(0, import_service_utils.hasOwnDefined)(changes, "colorField") ? { colorField: { colorFieldName: fieldNames.colorFieldName || "" } } : {},
9791
10178
  ...(0, import_service_utils.hasOwnDefined)(changes, "startField") ? { startDateField: { start: fieldNames.start } } : {},
9792
10179
  ...(0, import_service_utils.hasOwnDefined)(changes, "endField") ? { endDateField: { end: fieldNames.end || "" } } : {},
9793
- ...(0, import_service_utils.hasOwnDefined)(changes, "defaultView") ? { defaultView: { defaultView: changes.defaultView } } : {},
9794
- ...(0, import_service_utils.hasOwnDefined)(changes, "quickCreateEvent") ? { quickCreateEvent: { enableQuickCreateEvent: changes.quickCreateEvent !== false } } : {},
9795
- ...(0, import_service_utils.hasOwnDefined)(changes, "showLunar") ? { showLunar: { showLunar: changes.showLunar === true } } : {},
9796
- ...(0, import_service_utils.hasOwnDefined)(changes, "weekStart") ? { weekStart: { weekStart: changes.weekStart } } : {},
10180
+ ...(0, import_service_utils.hasOwnDefined)(changes, "defaultView") ? { defaultView: { defaultView } } : {},
10181
+ ...(0, import_service_utils.hasOwnDefined)(changes, "quickCreateEvent") ? { quickCreateEvent: { enableQuickCreateEvent: quickCreateEvent !== false } } : {},
10182
+ ...(0, import_service_utils.hasOwnDefined)(changes, "showLunar") ? { showLunar: { showLunar: showLunar === true } } : {},
10183
+ ...(0, import_service_utils.hasOwnDefined)(changes, "weekStart") ? { weekStart: { weekStart } } : {},
9797
10184
  ...(0, import_service_utils.hasOwnDefined)(changes, "dataScope") ? { dataScope: { filter: changes.dataScope } } : {},
9798
10185
  ...(0, import_service_utils.hasOwnDefined)(changes, "linkageRules") ? { linkageRules: { value: changes.linkageRules } } : {}
9799
10186
  })
@@ -9809,72 +10196,29 @@ class FlowSurfacesService {
9809
10196
  await this.ensureCalendarBlockPopupHosts(reloaded, options.transaction);
9810
10197
  return result;
9811
10198
  }
9812
- async configureFormBlock(target, use, changes, options) {
9813
- const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)(use);
10199
+ async configureTreeBlock(target, current, changes, options) {
10200
+ var _a, _b;
10201
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("TreeBlockModel");
9814
10202
  const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
9815
- (0, import_service_utils.assertSupportedSimpleChanges)("form", changes, allowedKeys);
9816
- const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
9817
- const nextStepParams = {};
9818
- if (cardSettings) {
9819
- nextStepParams.cardSettings = cardSettings;
9820
- }
9821
- if (changes.resource) {
9822
- nextStepParams.resourceSettings = {
9823
- init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
9824
- };
9825
- }
9826
- if ((0, import_service_utils.hasDefinedValue)(changes, ["layout", "labelAlign", "labelWidth", "labelWrap", "assignRules", "colon"])) {
9827
- nextStepParams.formModelSettings = (0, import_service_utils.buildDefinedPayload)({
9828
- ...(0, import_service_utils.hasOwnDefined)(changes, "layout") || (0, import_service_utils.hasOwnDefined)(changes, "labelAlign") || (0, import_service_utils.hasOwnDefined)(changes, "labelWidth") || (0, import_service_utils.hasOwnDefined)(changes, "labelWrap") || (0, import_service_utils.hasOwnDefined)(changes, "colon") ? {
9829
- layout: (0, import_service_utils.buildDefinedPayload)({
9830
- layout: layoutValue,
9831
- labelAlign: changes.labelAlign,
9832
- labelWidth: changes.labelWidth,
9833
- labelWrap: changes.labelWrap,
9834
- colon: changes.colon
9835
- })
9836
- } : {},
9837
- ...(0, import_service_utils.hasOwnDefined)(changes, "assignRules") ? { assignRules: { value: changes.assignRules } } : {}
9838
- });
9839
- }
9840
- if (use === "EditFormModel" && (0, import_service_utils.hasOwnDefined)(changes, "dataScope")) {
9841
- nextStepParams.formSettings = {
9842
- dataScope: {
9843
- filter: changes.dataScope
9844
- }
9845
- };
10203
+ (0, import_service_utils.assertSupportedSimpleChanges)("tree", changes, allowedKeys);
10204
+ const nextFieldNames = import_lodash.default.isPlainObject(changes.fieldNames) ? import_lodash.default.merge({}, ((_a = current == null ? void 0 : current.props) == null ? void 0 : _a.fieldNames) || {}, changes.fieldNames) : import_lodash.default.cloneDeep(((_b = current == null ? void 0 : current.props) == null ? void 0 : _b.fieldNames) || {});
10205
+ if ((0, import_service_utils.hasOwnDefined)(changes, "titleField")) {
10206
+ nextFieldNames.title = String(changes.titleField || "").trim();
9846
10207
  }
10208
+ const hasFieldNamesPatch = (0, import_service_utils.hasOwnDefined)(changes, "titleField") || import_lodash.default.isPlainObject(changes.fieldNames);
9847
10209
  return this.updateSettings(
9848
10210
  {
9849
10211
  target,
9850
10212
  props: (0, import_service_utils.buildDefinedPayload)({
9851
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
9852
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
9853
- }),
9854
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
9855
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
9856
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
9857
- }),
9858
- stepParams: Object.keys(nextStepParams).length ? nextStepParams : void 0
9859
- },
9860
- options
9861
- );
9862
- }
9863
- async configureDetailsBlock(target, changes, options) {
9864
- const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("DetailsBlockModel");
9865
- const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
9866
- (0, import_service_utils.assertSupportedSimpleChanges)("details", changes, allowedKeys);
9867
- const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
9868
- return this.updateSettings(
9869
- {
9870
- target,
9871
- props: (0, import_service_utils.buildDefinedPayload)({
9872
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
9873
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
10213
+ ...(0, import_service_utils.hasOwnDefined)(changes, "searchable") ? { searchable: changes.searchable !== false } : {},
10214
+ ...(0, import_service_utils.hasOwnDefined)(changes, "defaultExpandAll") ? { defaultExpandAll: changes.defaultExpandAll === true } : {},
10215
+ ...(0, import_service_utils.hasOwnDefined)(changes, "includeDescendants") ? { includeDescendants: changes.includeDescendants !== false } : {},
10216
+ ...hasFieldNamesPatch ? { fieldNames: nextFieldNames } : {},
10217
+ ...(0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? { pageSize: changes.pageSize } : {}
9874
10218
  }),
9875
10219
  decoratorProps: (0, import_service_utils.buildDefinedPayload)({
9876
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
9877
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
10220
+ height: changes.height,
10221
+ heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
9878
10222
  }),
9879
10223
  stepParams: {
9880
10224
  ...cardSettings ? { cardSettings } : {},
@@ -9884,28 +10228,22 @@ class FlowSurfacesService {
9884
10228
  }
9885
10229
  } : {},
9886
10230
  ...(0, import_service_utils.hasDefinedValue)(changes, [
9887
- "layout",
9888
- "labelAlign",
9889
- "labelWidth",
9890
- "labelWrap",
9891
- "colon",
9892
- "sorting",
10231
+ "searchable",
10232
+ "defaultExpandAll",
10233
+ "includeDescendants",
10234
+ "titleField",
10235
+ "pageSize",
9893
10236
  "dataScope",
9894
- "linkageRules"
10237
+ "sorting"
9895
10238
  ]) ? {
9896
- detailsSettings: (0, import_service_utils.buildDefinedPayload)({
9897
- ...(0, import_service_utils.hasOwnDefined)(changes, "layout") || (0, import_service_utils.hasOwnDefined)(changes, "labelAlign") || (0, import_service_utils.hasOwnDefined)(changes, "labelWidth") || (0, import_service_utils.hasOwnDefined)(changes, "labelWrap") || (0, import_service_utils.hasOwnDefined)(changes, "colon") ? {
9898
- layout: (0, import_service_utils.buildDefinedPayload)({
9899
- layout: layoutValue,
9900
- labelAlign: changes.labelAlign,
9901
- labelWidth: changes.labelWidth,
9902
- labelWrap: changes.labelWrap,
9903
- colon: changes.colon
9904
- })
9905
- } : {},
9906
- ...(0, import_service_utils.hasOwnDefined)(changes, "sorting") ? { defaultSorting: { sort: changes.sorting } } : {},
10239
+ treeSettings: (0, import_service_utils.buildDefinedPayload)({
10240
+ ...(0, import_service_utils.hasOwnDefined)(changes, "searchable") ? { searchable: { searchable: changes.searchable !== false } } : {},
10241
+ ...(0, import_service_utils.hasOwnDefined)(changes, "defaultExpandAll") ? { defaultExpandAll: { defaultExpandAll: changes.defaultExpandAll === true } } : {},
10242
+ ...(0, import_service_utils.hasOwnDefined)(changes, "includeDescendants") ? { includeDescendants: { includeDescendants: changes.includeDescendants !== false } } : {},
10243
+ ...(0, import_service_utils.hasOwnDefined)(changes, "titleField") ? { titleField: { titleField: nextFieldNames.title } } : {},
10244
+ ...(0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? { pageSize: { pageSize: changes.pageSize } } : {},
9907
10245
  ...(0, import_service_utils.hasOwnDefined)(changes, "dataScope") ? { dataScope: { filter: changes.dataScope } } : {},
9908
- ...(0, import_service_utils.hasOwnDefined)(changes, "linkageRules") ? { linkageRules: { value: changes.linkageRules } } : {}
10246
+ ...(0, import_service_utils.hasOwnDefined)(changes, "sorting") ? { defaultSorting: { sort: changes.sorting } } : {}
9909
10247
  })
9910
10248
  } : {}
9911
10249
  }
@@ -9913,23 +10251,447 @@ class FlowSurfacesService {
9913
10251
  options
9914
10252
  );
9915
10253
  }
9916
- async configureFilterFormBlock(target, changes, options) {
9917
- const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("FilterFormBlockModel");
9918
- (0, import_service_utils.assertSupportedSimpleChanges)("filterForm", changes, allowedKeys);
9919
- const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
9920
- return this.updateSettings(
9921
- {
9922
- target,
9923
- props: (0, import_service_utils.buildDefinedPayload)({
9924
- title: changes.title,
9925
- displayTitle: changes.displayTitle,
9926
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
9927
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
9928
- }),
9929
- decoratorProps: (0, import_service_utils.buildDefinedPayload)({
9930
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
9931
- ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
9932
- }),
10254
+ async configureKanbanBlock(target, current, changes, options) {
10255
+ var _a;
10256
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("KanbanBlockModel");
10257
+ const blockCardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10258
+ (0, import_service_utils.assertSupportedSimpleChanges)("kanban", changes, allowedKeys);
10259
+ if (!import_lodash.default.isUndefined(changes.dragEnabled) && !import_lodash.default.isBoolean(changes.dragEnabled)) {
10260
+ (0, import_errors.throwBadRequest)("flowSurfaces configure kanban dragEnabled must be a boolean");
10261
+ }
10262
+ if (!import_lodash.default.isUndefined(changes.quickCreateEnabled) && !import_lodash.default.isBoolean(changes.quickCreateEnabled)) {
10263
+ (0, import_errors.throwBadRequest)("flowSurfaces configure kanban quickCreateEnabled must be a boolean");
10264
+ }
10265
+ if (!import_lodash.default.isUndefined(changes.enableCardClick) && !import_lodash.default.isBoolean(changes.enableCardClick)) {
10266
+ (0, import_errors.throwBadRequest)("flowSurfaces configure kanban enableCardClick must be a boolean");
10267
+ }
10268
+ if (!import_lodash.default.isUndefined(changes.cardLabelWrap) && !import_lodash.default.isBoolean(changes.cardLabelWrap)) {
10269
+ (0, import_errors.throwBadRequest)("flowSurfaces configure kanban cardLabelWrap must be a boolean");
10270
+ }
10271
+ if (!import_lodash.default.isUndefined(changes.cardColon) && !import_lodash.default.isBoolean(changes.cardColon)) {
10272
+ (0, import_errors.throwBadRequest)("flowSurfaces configure kanban cardColon must be a boolean");
10273
+ }
10274
+ if (!import_lodash.default.isUndefined(changes.styleVariant)) {
10275
+ const normalizedStyleVariant = String(changes.styleVariant || "").trim();
10276
+ if (normalizedStyleVariant !== "default" && normalizedStyleVariant !== "filled") {
10277
+ (0, import_errors.throwBadRequest)(`flowSurfaces configure kanban styleVariant must be 'default' or 'filled'`);
10278
+ }
10279
+ }
10280
+ const currentResourceInit = this.getKanbanBlockResourceInit(current);
10281
+ const nextResourceInit = changes.resource ? (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource) : currentResourceInit;
10282
+ if (nextResourceInit.collectionName && !nextResourceInit.dataSourceKey) {
10283
+ nextResourceInit.dataSourceKey = "main";
10284
+ }
10285
+ const resourceChanged = !!changes.resource;
10286
+ const { collection, collectionName, dataSourceKey } = this.assertKanbanCollectionCompatible(
10287
+ "configure",
10288
+ nextResourceInit
10289
+ );
10290
+ const currentItemNode = (0, import_service_utils.getSingleNodeSubModel)((_a = current == null ? void 0 : current.subModels) == null ? void 0 : _a.item);
10291
+ if (!(currentItemNode == null ? void 0 : currentItemNode.uid)) {
10292
+ (0, import_errors.throwConflict)(
10293
+ `flowSurfaces configure kanban block '${(current == null ? void 0 : current.uid) || target.uid}' is missing its item subtree`,
10294
+ "FLOW_SURFACE_KANBAN_ITEM_SUBTREE_MISSING"
10295
+ );
10296
+ }
10297
+ const currentProps = import_lodash.default.cloneDeep((current == null ? void 0 : current.props) || {});
10298
+ const currentGroupFieldName = String(currentProps.groupField || this.getKanbanDefaultGroupFieldName(collection) || "").trim() || void 0;
10299
+ let nextGroupFieldName = (0, import_service_utils.hasOwnDefined)(changes, "groupField") ? this.normalizeKanbanFieldNameInput(changes.groupField, "flowSurfaces configure kanban groupField", {
10300
+ allowEmpty: true
10301
+ }) || void 0 : currentGroupFieldName;
10302
+ let nextGroupField = this.getKanbanGroupField(collection, nextGroupFieldName);
10303
+ if (!nextGroupField || !this.isKanbanGroupField(nextGroupField)) {
10304
+ nextGroupFieldName = this.getKanbanDefaultGroupFieldName(collection);
10305
+ nextGroupField = this.getKanbanGroupField(collection, nextGroupFieldName);
10306
+ }
10307
+ if (!nextGroupFieldName || !nextGroupField || !this.isKanbanGroupField(nextGroupField)) {
10308
+ (0, import_errors.throwBadRequest)(
10309
+ `flowSurfaces configure kanban collection '${dataSourceKey}.${collectionName}' must resolve a supported groupField`
10310
+ );
10311
+ }
10312
+ const groupFieldChanged = resourceChanged || nextGroupFieldName !== currentGroupFieldName;
10313
+ const isRelationGroupField = this.isKanbanAssociationGroupField(nextGroupField);
10314
+ const defaultGroupTitleField = this.getKanbanDefaultRelationTitleFieldName(nextGroupField, dataSourceKey);
10315
+ const nextGroupTitleField = isRelationGroupField ? (() => {
10316
+ const requested = (0, import_service_utils.hasOwnDefined)(changes, "groupTitleField") ? this.normalizeKanbanFieldNameInput(
10317
+ changes.groupTitleField,
10318
+ "flowSurfaces configure kanban groupTitleField",
10319
+ { allowEmpty: true }
10320
+ ) || void 0 : groupFieldChanged ? defaultGroupTitleField : this.normalizeKanbanFieldNameInput(currentProps.groupTitleField || defaultGroupTitleField, "", {
10321
+ allowEmpty: true
10322
+ }) || void 0;
10323
+ if (requested) {
10324
+ this.assertKanbanRelationFieldBinding({
10325
+ actionName: "configure",
10326
+ collectionName,
10327
+ dataSourceKey,
10328
+ groupField: nextGroupField,
10329
+ fieldName: requested,
10330
+ kind: "groupTitleField"
10331
+ });
10332
+ }
10333
+ return requested;
10334
+ })() : void 0;
10335
+ const nextGroupColorField = isRelationGroupField ? (() => {
10336
+ const requested = (0, import_service_utils.hasOwnDefined)(changes, "groupColorField") ? this.normalizeKanbanFieldNameInput(
10337
+ changes.groupColorField,
10338
+ "flowSurfaces configure kanban groupColorField",
10339
+ { allowEmpty: true }
10340
+ ) || void 0 : groupFieldChanged ? void 0 : this.normalizeKanbanFieldNameInput(currentProps.groupColorField, "", { allowEmpty: true }) || void 0;
10341
+ if (requested) {
10342
+ this.assertKanbanRelationFieldBinding({
10343
+ actionName: "configure",
10344
+ collectionName,
10345
+ dataSourceKey,
10346
+ groupField: nextGroupField,
10347
+ fieldName: requested,
10348
+ kind: "groupColorField"
10349
+ });
10350
+ }
10351
+ return requested;
10352
+ })() : void 0;
10353
+ const inlineGroupOptions = this.buildKanbanInlineGroupOptions(nextGroupField);
10354
+ const explicitGroupOptions = Object.prototype.hasOwnProperty.call(changes, "groupOptions") ? this.normalizeKanbanGroupOptions(changes.groupOptions, "flowSurfaces configure kanban groupOptions") : void 0;
10355
+ const currentGroupOptions = Array.isArray(currentProps.groupOptions) ? import_lodash.default.cloneDeep(currentProps.groupOptions) : void 0;
10356
+ const nextGroupOptions = this.mergeKanbanInlineGroupOptions(
10357
+ inlineGroupOptions,
10358
+ !import_lodash.default.isUndefined(explicitGroupOptions) ? explicitGroupOptions : groupFieldChanged ? inlineGroupOptions : currentGroupOptions,
10359
+ "flowSurfaces configure kanban groupOptions"
10360
+ );
10361
+ let nextDragSortBy;
10362
+ if ((0, import_service_utils.hasOwnDefined)(changes, "dragSortBy")) {
10363
+ const requested = this.resolveKanbanCompatibleSortFieldName({
10364
+ actionName: "configure",
10365
+ collection,
10366
+ groupField: nextGroupField,
10367
+ requested: changes.dragSortBy,
10368
+ allowEmpty: true
10369
+ });
10370
+ nextDragSortBy = requested || void 0;
10371
+ } else {
10372
+ try {
10373
+ const requested = currentProps.dragSortBy ? this.resolveKanbanCompatibleSortFieldName({
10374
+ actionName: "configure",
10375
+ collection,
10376
+ groupField: nextGroupField,
10377
+ requested: currentProps.dragSortBy,
10378
+ allowEmpty: true
10379
+ }) : void 0;
10380
+ nextDragSortBy = requested || void 0;
10381
+ } catch (error) {
10382
+ nextDragSortBy = void 0;
10383
+ }
10384
+ }
10385
+ const requestedDragEnabled = (0, import_service_utils.hasOwnDefined)(changes, "dragEnabled") ? changes.dragEnabled : currentProps.dragEnabled;
10386
+ const nextDragEnabled = requestedDragEnabled === true && !!nextDragSortBy;
10387
+ const nextStyleVariantProp = (0, import_service_utils.hasOwnDefined)(changes, "styleVariant") ? String(changes.styleVariant || "").trim() === "default" ? "default" : "color" : void 0;
10388
+ const nextStyleVariantSetting = (0, import_service_utils.hasOwnDefined)(changes, "styleVariant") ? String(changes.styleVariant || "").trim() : void 0;
10389
+ const quickCreatePopup = Object.prototype.hasOwnProperty.call(changes, "quickCreatePopup") ? await this.normalizeKanbanPopupConfigureValue({
10390
+ actionName: "configure kanban quickCreatePopup",
10391
+ blockUid: current.uid,
10392
+ actionKey: "quickCreateAction",
10393
+ value: changes.quickCreatePopup,
10394
+ transaction: options.transaction
10395
+ }) : void 0;
10396
+ const cardPopup = Object.prototype.hasOwnProperty.call(changes, "cardPopup") ? await this.normalizeKanbanPopupConfigureValue({
10397
+ actionName: "configure kanban cardPopup",
10398
+ blockUid: current.uid,
10399
+ actionKey: "cardViewAction",
10400
+ value: changes.cardPopup,
10401
+ transaction: options.transaction
10402
+ }) : void 0;
10403
+ const nextCardLayout = (0, import_service_utils.hasOwnDefined)(changes, "cardLayout") ? (0, import_service_utils.normalizeSimpleLayoutValue)(changes.cardLayout) : void 0;
10404
+ const shouldWriteGrouping = resourceChanged || (0, import_service_utils.hasOwnDefined)(changes, "groupField") || (0, import_service_utils.hasOwnDefined)(changes, "groupTitleField") || (0, import_service_utils.hasOwnDefined)(changes, "groupColorField") || (0, import_service_utils.hasOwnDefined)(changes, "groupOptions") || groupFieldChanged;
10405
+ const shouldWriteDrag = resourceChanged || (0, import_service_utils.hasOwnDefined)(changes, "dragEnabled") || (0, import_service_utils.hasOwnDefined)(changes, "dragSortBy") || groupFieldChanged;
10406
+ const blockProps = (0, import_service_utils.buildDefinedPayload)({
10407
+ ...shouldWriteGrouping ? {
10408
+ groupField: nextGroupFieldName,
10409
+ groupTitleField: nextGroupTitleField ?? null,
10410
+ groupColorField: nextGroupColorField ?? null,
10411
+ groupOptions: nextGroupOptions || []
10412
+ } : {},
10413
+ ...(0, import_service_utils.hasOwnDefined)(changes, "styleVariant") ? { styleVariant: nextStyleVariantProp } : {},
10414
+ ...(0, import_service_utils.hasOwnDefined)(changes, "sorting") ? { globalSort: changes.sorting } : {},
10415
+ ...shouldWriteDrag ? {
10416
+ dragEnabled: nextDragEnabled,
10417
+ dragSortBy: nextDragSortBy ?? null
10418
+ } : {},
10419
+ ...(0, import_service_utils.hasOwnDefined)(changes, "quickCreateEnabled") ? {
10420
+ quickCreateEnabled: changes.quickCreateEnabled === true
10421
+ } : {},
10422
+ ...(0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? { pageSize: changes.pageSize } : {},
10423
+ ...(0, import_service_utils.hasOwnDefined)(changes, "columnWidth") ? { columnWidth: changes.columnWidth } : {},
10424
+ ...(0, import_service_utils.hasOwnDefined)(changes, "quickCreatePopup") ? {
10425
+ popupMode: (quickCreatePopup == null ? void 0 : quickCreatePopup.mode) ?? null,
10426
+ popupSize: (quickCreatePopup == null ? void 0 : quickCreatePopup.size) ?? null,
10427
+ popupTemplateUid: (quickCreatePopup == null ? void 0 : quickCreatePopup.popupTemplateUid) ?? null,
10428
+ popupPageModelClass: (quickCreatePopup == null ? void 0 : quickCreatePopup.pageModelClass) ?? null,
10429
+ popupTargetUid: (quickCreatePopup == null ? void 0 : quickCreatePopup.uid) ?? null
10430
+ } : {}
10431
+ });
10432
+ const blockStepParams = (0, import_service_utils.buildDefinedPayload)({
10433
+ ...blockCardSettings ? { cardSettings: blockCardSettings } : {},
10434
+ ...changes.resource ? {
10435
+ resourceSettings: {
10436
+ init: nextResourceInit
10437
+ }
10438
+ } : {},
10439
+ ...shouldWriteGrouping || (0, import_service_utils.hasOwnDefined)(changes, "styleVariant") || (0, import_service_utils.hasOwnDefined)(changes, "sorting") || shouldWriteDrag || (0, import_service_utils.hasOwnDefined)(changes, "quickCreateEnabled") || (0, import_service_utils.hasOwnDefined)(changes, "quickCreatePopup") || (0, import_service_utils.hasOwnDefined)(changes, "pageSize") || (0, import_service_utils.hasOwnDefined)(changes, "columnWidth") || (0, import_service_utils.hasOwnDefined)(changes, "dataScope") ? {
10440
+ kanbanSettings: (0, import_service_utils.buildDefinedPayload)({
10441
+ ...shouldWriteGrouping ? {
10442
+ grouping: (0, import_service_utils.buildDefinedPayload)({
10443
+ groupField: nextGroupFieldName,
10444
+ groupTitleField: nextGroupTitleField ?? null,
10445
+ groupColorField: nextGroupColorField ?? null,
10446
+ groupOptions: nextGroupOptions || []
10447
+ })
10448
+ } : {},
10449
+ ...(0, import_service_utils.hasOwnDefined)(changes, "styleVariant") ? {
10450
+ styleVariant: {
10451
+ styleVariant: nextStyleVariantSetting
10452
+ }
10453
+ } : {},
10454
+ ...(0, import_service_utils.hasOwnDefined)(changes, "sorting") ? {
10455
+ defaultSorting: {
10456
+ sort: changes.sorting
10457
+ }
10458
+ } : {},
10459
+ ...shouldWriteDrag ? {
10460
+ dragEnabled: {
10461
+ dragEnabled: nextDragEnabled
10462
+ },
10463
+ dragSortBy: {
10464
+ dragSortBy: nextDragSortBy ?? null
10465
+ }
10466
+ } : {},
10467
+ ...(0, import_service_utils.hasOwnDefined)(changes, "quickCreateEnabled") ? {
10468
+ quickCreate: {
10469
+ quickCreateEnabled: changes.quickCreateEnabled === true
10470
+ }
10471
+ } : {},
10472
+ ...(0, import_service_utils.hasOwnDefined)(changes, "quickCreatePopup") ? {
10473
+ popup: quickCreatePopup || {}
10474
+ } : {},
10475
+ ...(0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? {
10476
+ pageSize: {
10477
+ pageSize: changes.pageSize
10478
+ }
10479
+ } : {},
10480
+ ...(0, import_service_utils.hasOwnDefined)(changes, "columnWidth") ? {
10481
+ columnWidth: {
10482
+ columnWidth: changes.columnWidth
10483
+ }
10484
+ } : {},
10485
+ ...(0, import_service_utils.hasOwnDefined)(changes, "dataScope") ? {
10486
+ dataScope: {
10487
+ filter: changes.dataScope
10488
+ }
10489
+ } : {}
10490
+ })
10491
+ } : {}
10492
+ });
10493
+ const itemProps = (0, import_service_utils.buildDefinedPayload)({
10494
+ ...(0, import_service_utils.hasOwnDefined)(changes, "enableCardClick") ? {
10495
+ enableCardClick: changes.enableCardClick === true
10496
+ } : {},
10497
+ ...(0, import_service_utils.hasOwnDefined)(changes, "cardPopup") ? {
10498
+ openMode: (cardPopup == null ? void 0 : cardPopup.mode) ?? null,
10499
+ popupSize: (cardPopup == null ? void 0 : cardPopup.size) ?? null,
10500
+ popupTemplateUid: (cardPopup == null ? void 0 : cardPopup.popupTemplateUid) ?? null,
10501
+ pageModelClass: (cardPopup == null ? void 0 : cardPopup.pageModelClass) ?? null,
10502
+ popupTargetUid: (cardPopup == null ? void 0 : cardPopup.uid) ?? null
10503
+ } : {},
10504
+ ...(0, import_service_utils.hasOwnDefined)(changes, "cardLayout") ? {
10505
+ layout: nextCardLayout
10506
+ } : {},
10507
+ ...(0, import_service_utils.hasOwnDefined)(changes, "cardLabelAlign") ? { labelAlign: changes.cardLabelAlign } : {},
10508
+ ...(0, import_service_utils.hasOwnDefined)(changes, "cardLabelWidth") ? { labelWidth: changes.cardLabelWidth ?? null } : {},
10509
+ ...(0, import_service_utils.hasOwnDefined)(changes, "cardLabelWrap") ? { labelWrap: changes.cardLabelWrap === true } : {},
10510
+ ...(0, import_service_utils.hasOwnDefined)(changes, "cardColon") ? { colon: changes.cardColon === true } : {}
10511
+ });
10512
+ const itemStepParams = (0, import_service_utils.buildDefinedPayload)({
10513
+ ...(0, import_service_utils.hasOwnDefined)(changes, "enableCardClick") || (0, import_service_utils.hasOwnDefined)(changes, "cardPopup") || (0, import_service_utils.hasOwnDefined)(changes, "cardLayout") || (0, import_service_utils.hasOwnDefined)(changes, "cardLabelAlign") || (0, import_service_utils.hasOwnDefined)(changes, "cardLabelWidth") || (0, import_service_utils.hasOwnDefined)(changes, "cardLabelWrap") || (0, import_service_utils.hasOwnDefined)(changes, "cardColon") ? {
10514
+ cardSettings: (0, import_service_utils.buildDefinedPayload)({
10515
+ ...(0, import_service_utils.hasOwnDefined)(changes, "enableCardClick") ? {
10516
+ click: {
10517
+ enableCardClick: changes.enableCardClick === true
10518
+ }
10519
+ } : {},
10520
+ ...(0, import_service_utils.hasOwnDefined)(changes, "cardPopup") ? {
10521
+ popup: cardPopup || {}
10522
+ } : {},
10523
+ ...(0, import_service_utils.hasOwnDefined)(changes, "cardLayout") || (0, import_service_utils.hasOwnDefined)(changes, "cardLabelAlign") || (0, import_service_utils.hasOwnDefined)(changes, "cardLabelWidth") || (0, import_service_utils.hasOwnDefined)(changes, "cardLabelWrap") || (0, import_service_utils.hasOwnDefined)(changes, "cardColon") ? {
10524
+ layout: (0, import_service_utils.buildDefinedPayload)({
10525
+ layout: nextCardLayout,
10526
+ labelAlign: changes.cardLabelAlign,
10527
+ labelWidth: (0, import_service_utils.hasOwnDefined)(changes, "cardLabelWidth") ? changes.cardLabelWidth ?? null : void 0,
10528
+ labelWrap: (0, import_service_utils.hasOwnDefined)(changes, "cardLabelWrap") ? changes.cardLabelWrap === true : void 0,
10529
+ colon: (0, import_service_utils.hasOwnDefined)(changes, "cardColon") ? changes.cardColon === true : void 0
10530
+ })
10531
+ } : {}
10532
+ })
10533
+ } : {}
10534
+ });
10535
+ const updated = /* @__PURE__ */ new Set();
10536
+ if (Object.keys(blockProps).length || Object.keys(blockStepParams).length || (0, import_service_utils.hasDefinedValue)(changes, ["height", "heightMode"])) {
10537
+ const blockResult = await this.updateSettings(
10538
+ {
10539
+ target,
10540
+ props: blockProps,
10541
+ decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10542
+ height: changes.height,
10543
+ heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10544
+ }),
10545
+ stepParams: blockStepParams
10546
+ },
10547
+ options
10548
+ );
10549
+ import_lodash.default.castArray((blockResult == null ? void 0 : blockResult.updated) || []).forEach((key) => updated.add(String(key)));
10550
+ }
10551
+ if (Object.keys(itemProps).length || Object.keys(itemStepParams).length) {
10552
+ const itemResult = await this.updateSettings(
10553
+ {
10554
+ target: {
10555
+ uid: currentItemNode.uid
10556
+ },
10557
+ props: itemProps,
10558
+ stepParams: itemStepParams
10559
+ },
10560
+ options
10561
+ );
10562
+ import_lodash.default.castArray((itemResult == null ? void 0 : itemResult.updated) || []).forEach((key) => updated.add(String(key)));
10563
+ }
10564
+ const reloaded = await this.repository.findModelById(current.uid, {
10565
+ transaction: options.transaction,
10566
+ includeAsyncNode: true
10567
+ });
10568
+ await this.ensureKanbanBlockPopupHosts(reloaded, options.transaction);
10569
+ return (0, import_service_utils.buildDefinedPayload)({
10570
+ uid: current.uid,
10571
+ ...updated.size ? { updated: Array.from(updated) } : {}
10572
+ });
10573
+ }
10574
+ async configureFormBlock(target, use, changes, options) {
10575
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)(use);
10576
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10577
+ (0, import_service_utils.assertSupportedSimpleChanges)("form", changes, allowedKeys);
10578
+ const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
10579
+ const nextStepParams = {};
10580
+ if (cardSettings) {
10581
+ nextStepParams.cardSettings = cardSettings;
10582
+ }
10583
+ if (changes.resource) {
10584
+ nextStepParams.resourceSettings = {
10585
+ init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
10586
+ };
10587
+ }
10588
+ if ((0, import_service_utils.hasDefinedValue)(changes, ["layout", "labelAlign", "labelWidth", "labelWrap", "assignRules", "colon"])) {
10589
+ nextStepParams.formModelSettings = (0, import_service_utils.buildDefinedPayload)({
10590
+ ...(0, import_service_utils.hasOwnDefined)(changes, "layout") || (0, import_service_utils.hasOwnDefined)(changes, "labelAlign") || (0, import_service_utils.hasOwnDefined)(changes, "labelWidth") || (0, import_service_utils.hasOwnDefined)(changes, "labelWrap") || (0, import_service_utils.hasOwnDefined)(changes, "colon") ? {
10591
+ layout: (0, import_service_utils.buildDefinedPayload)({
10592
+ layout: layoutValue,
10593
+ labelAlign: changes.labelAlign,
10594
+ labelWidth: changes.labelWidth,
10595
+ labelWrap: changes.labelWrap,
10596
+ colon: changes.colon
10597
+ })
10598
+ } : {},
10599
+ ...(0, import_service_utils.hasOwnDefined)(changes, "assignRules") ? { assignRules: { value: changes.assignRules } } : {}
10600
+ });
10601
+ }
10602
+ if (use === "EditFormModel" && (0, import_service_utils.hasOwnDefined)(changes, "dataScope")) {
10603
+ nextStepParams.formSettings = {
10604
+ dataScope: {
10605
+ filter: changes.dataScope
10606
+ }
10607
+ };
10608
+ }
10609
+ return this.updateSettings(
10610
+ {
10611
+ target,
10612
+ props: (0, import_service_utils.buildDefinedPayload)({
10613
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
10614
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
10615
+ }),
10616
+ decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10617
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
10618
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
10619
+ }),
10620
+ stepParams: Object.keys(nextStepParams).length ? nextStepParams : void 0
10621
+ },
10622
+ options
10623
+ );
10624
+ }
10625
+ async configureDetailsBlock(target, changes, options) {
10626
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("DetailsBlockModel");
10627
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10628
+ (0, import_service_utils.assertSupportedSimpleChanges)("details", changes, allowedKeys);
10629
+ const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
10630
+ return this.updateSettings(
10631
+ {
10632
+ target,
10633
+ props: (0, import_service_utils.buildDefinedPayload)({
10634
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
10635
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
10636
+ }),
10637
+ decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10638
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
10639
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
10640
+ }),
10641
+ stepParams: {
10642
+ ...cardSettings ? { cardSettings } : {},
10643
+ ...changes.resource ? {
10644
+ resourceSettings: {
10645
+ init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
10646
+ }
10647
+ } : {},
10648
+ ...(0, import_service_utils.hasDefinedValue)(changes, [
10649
+ "layout",
10650
+ "labelAlign",
10651
+ "labelWidth",
10652
+ "labelWrap",
10653
+ "colon",
10654
+ "sorting",
10655
+ "dataScope",
10656
+ "linkageRules"
10657
+ ]) ? {
10658
+ detailsSettings: (0, import_service_utils.buildDefinedPayload)({
10659
+ ...(0, import_service_utils.hasOwnDefined)(changes, "layout") || (0, import_service_utils.hasOwnDefined)(changes, "labelAlign") || (0, import_service_utils.hasOwnDefined)(changes, "labelWidth") || (0, import_service_utils.hasOwnDefined)(changes, "labelWrap") || (0, import_service_utils.hasOwnDefined)(changes, "colon") ? {
10660
+ layout: (0, import_service_utils.buildDefinedPayload)({
10661
+ layout: layoutValue,
10662
+ labelAlign: changes.labelAlign,
10663
+ labelWidth: changes.labelWidth,
10664
+ labelWrap: changes.labelWrap,
10665
+ colon: changes.colon
10666
+ })
10667
+ } : {},
10668
+ ...(0, import_service_utils.hasOwnDefined)(changes, "sorting") ? { defaultSorting: { sort: changes.sorting } } : {},
10669
+ ...(0, import_service_utils.hasOwnDefined)(changes, "dataScope") ? { dataScope: { filter: changes.dataScope } } : {},
10670
+ ...(0, import_service_utils.hasOwnDefined)(changes, "linkageRules") ? { linkageRules: { value: changes.linkageRules } } : {}
10671
+ })
10672
+ } : {}
10673
+ }
10674
+ },
10675
+ options
10676
+ );
10677
+ }
10678
+ async configureFilterFormBlock(target, changes, options) {
10679
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("FilterFormBlockModel");
10680
+ (0, import_service_utils.assertSupportedSimpleChanges)("filterForm", changes, allowedKeys);
10681
+ const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
10682
+ return this.updateSettings(
10683
+ {
10684
+ target,
10685
+ props: (0, import_service_utils.buildDefinedPayload)({
10686
+ title: changes.title,
10687
+ displayTitle: changes.displayTitle,
10688
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
10689
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
10690
+ }),
10691
+ decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10692
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
10693
+ ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
10694
+ }),
9933
10695
  stepParams: {
9934
10696
  ...changes.resource ? {
9935
10697
  resourceSettings: {
@@ -10357,10 +11119,22 @@ class FlowSurfacesService {
10357
11119
  );
10358
11120
  }
10359
11121
  async configureFieldWrapper(target, current, changes, options) {
10360
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
11122
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
10361
11123
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
10362
11124
  (0, import_service_utils.assertSupportedSimpleChanges)("field wrapper", changes, (0, import_configure_options.getConfigureOptionKeysForUse)(current == null ? void 0 : current.use));
10363
- const rawWrapperChanges = import_lodash.default.omit(changes, ["clickToOpen", "openView", "code", "version", "fieldComponent"]);
11125
+ const rawWrapperChanges = import_lodash.default.omit(changes, [
11126
+ "clickToOpen",
11127
+ "openView",
11128
+ "code",
11129
+ "version",
11130
+ "fieldType",
11131
+ "fields",
11132
+ "selectorFields",
11133
+ "openMode",
11134
+ "popupSize",
11135
+ "pageSize",
11136
+ "showIndex"
11137
+ ]);
10364
11138
  const wrapperChanges = (current == null ? void 0 : current.use) === "TableColumnModel" && !(0, import_service_utils.hasOwnDefined)(rawWrapperChanges, "title") && (0, import_service_utils.hasOwnDefined)(rawWrapperChanges, "label") ? {
10365
11139
  ...rawWrapperChanges,
10366
11140
  title: rawWrapperChanges.label
@@ -10394,6 +11168,8 @@ class FlowSurfacesService {
10394
11168
  });
10395
11169
  const shouldSyncTitleField = titleFieldSyncDecision.shouldSync;
10396
11170
  const syncedTitleField = titleFieldSyncDecision.titleField;
11171
+ const shouldPatchTableColumnTitle = (current == null ? void 0 : current.use) === "TableColumnModel" && (0, import_service_utils.hasOwnDefined)(wrapperChanges, "title");
11172
+ const shouldPatchFieldSettings = (0, import_service_utils.hasDefinedValue)(wrapperChanges, ["fieldPath", "associationPathName"]) || shouldPatchTableColumnTitle;
10397
11173
  if (Object.keys(wrapperChanges).length) {
10398
11174
  await this.updateSettings(
10399
11175
  {
@@ -10428,8 +11204,8 @@ class FlowSurfacesService {
10428
11204
  labelWidth: wrapperChanges.labelWidth,
10429
11205
  labelWrap: wrapperChanges.labelWrap
10430
11206
  }),
10431
- 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)({
10432
- ...(current == null ? void 0 : current.use) === "TableColumnModel" && (0, import_service_utils.hasOwnDefined)(wrapperChanges, "title") ? {
11207
+ stepParams: shouldPatchFieldSettings ? (0, import_service_utils.buildDefinedPayload)({
11208
+ ...shouldPatchTableColumnTitle ? {
10433
11209
  tableColumnSettings: {
10434
11210
  title: {
10435
11211
  title: wrapperChanges.title
@@ -10465,24 +11241,69 @@ class FlowSurfacesService {
10465
11241
  );
10466
11242
  }
10467
11243
  }
10468
- if ((0, import_service_utils.hasOwnDefined)(changes, "fieldComponent")) {
11244
+ let effectiveInnerFieldUse = innerField == null ? void 0 : innerField.use;
11245
+ let fieldTypeResolution;
11246
+ let relationTitleFieldToApply;
11247
+ 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")) {
10469
11248
  if (!innerUid) {
10470
11249
  (0, import_errors.throwConflict)(
10471
11250
  `flowSurfaces configure field wrapper '${current == null ? void 0 : current.use}' cannot resolve inner field`,
10472
11251
  "FLOW_SURFACE_INNER_FIELD_MISSING"
10473
11252
  );
10474
11253
  }
11254
+ const fieldSource = this.resolveFieldComponentFieldSource(current, normalizedBinding);
11255
+ const currentPublicFieldType = (0, import_field_type_resolver.getPublicFieldTypeForUse)(
11256
+ ((_k = (_j = innerField == null ? void 0 : innerField.stepParams) == null ? void 0 : _j.fieldBinding) == null ? void 0 : _k.use) || (innerField == null ? void 0 : innerField.use)
11257
+ );
11258
+ const shouldApplyResolverDefaults = (0, import_service_utils.hasOwnDefined)(changes, "fieldType") && changes.fieldType !== currentPublicFieldType;
11259
+ fieldTypeResolution = (0, import_field_type_resolver.resolveRelationFieldType)({
11260
+ fieldType: (0, import_service_utils.hasOwnDefined)(changes, "fieldType") ? changes.fieldType : currentPublicFieldType,
11261
+ containerUse: current == null ? void 0 : current.use,
11262
+ field: fieldSource.field,
11263
+ dataSourceKey: (_l = fieldSource.fieldSettingsInit) == null ? void 0 : _l.dataSourceKey,
11264
+ getCollection: (dataSourceKey, collectionName) => this.getCollection(dataSourceKey, collectionName),
11265
+ fields: changes.fields,
11266
+ selectorFields: changes.selectorFields,
11267
+ titleField: (0, import_service_utils.hasOwnDefined)(wrapperChanges, "titleField") ? wrapperChanges.titleField : void 0,
11268
+ openMode: (0, import_service_utils.hasOwnDefined)(changes, "openMode") ? changes.openMode : void 0,
11269
+ popupSize: (0, import_service_utils.hasOwnDefined)(changes, "popupSize") ? changes.popupSize : void 0,
11270
+ pageSize: (0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? changes.pageSize : void 0,
11271
+ showIndex: (0, import_service_utils.hasOwnDefined)(changes, "showIndex") ? changes.showIndex : void 0,
11272
+ applyDefaults: shouldApplyResolverDefaults,
11273
+ context: "configure"
11274
+ });
11275
+ if (!fieldTypeResolution) {
11276
+ (0, import_errors.throwBadRequest)("flowSurfaces configure fieldType is required when configuring relation fields");
11277
+ }
11278
+ const shouldApplyFieldTypeDefaults = shouldApplyResolverDefaults;
11279
+ const shouldApplyRelationTitleField = (0, import_service_utils.hasOwnDefined)(wrapperChanges, "titleField") || shouldApplyFieldTypeDefaults;
11280
+ relationTitleFieldToApply = shouldApplyRelationTitleField ? fieldTypeResolution.titleField : void 0;
10475
11281
  const normalizedFieldComponentUse = await this.rebuildFieldSubModelOnServer({
10476
11282
  wrapperNode: current,
10477
11283
  innerField,
10478
- targetFieldUse: changes.fieldComponent,
11284
+ targetFieldUse: fieldTypeResolution.fieldUse,
10479
11285
  normalizedBinding,
10480
11286
  enabledPackages,
10481
11287
  transaction: options.transaction
10482
11288
  });
10483
- await this.syncFieldComponentStepParams(current, normalizedFieldComponentUse, options.transaction);
11289
+ effectiveInnerFieldUse = normalizedFieldComponentUse;
11290
+ await this.syncFieldTypeStepParams(current, normalizedFieldComponentUse, options.transaction);
11291
+ await this.applyResolvedRelationFieldType({
11292
+ fieldUid: innerUid,
11293
+ fieldUse: normalizedFieldComponentUse,
11294
+ targetCollection: fieldTypeResolution.targetCollection,
11295
+ fields: (0, import_service_utils.hasOwnDefined)(changes, "fields") || shouldApplyFieldTypeDefaults ? fieldTypeResolution.fields : void 0,
11296
+ selectorFields: (0, import_service_utils.hasOwnDefined)(changes, "selectorFields") || shouldApplyFieldTypeDefaults ? fieldTypeResolution.selectorFields : void 0,
11297
+ titleField: relationTitleFieldToApply,
11298
+ openMode: fieldTypeResolution.openMode,
11299
+ popupSize: fieldTypeResolution.popupSize,
11300
+ pageSize: fieldTypeResolution.pageSize,
11301
+ showIndex: fieldTypeResolution.showIndex,
11302
+ transaction: options.transaction
11303
+ });
10484
11304
  }
10485
- if (shouldSyncTitleField) {
11305
+ const effectiveSyncedTitleField = relationTitleFieldToApply ?? syncedTitleField;
11306
+ if ((shouldSyncTitleField || !import_lodash.default.isUndefined(relationTitleFieldToApply)) && this.supportsFieldTitleFieldProp(effectiveInnerFieldUse)) {
10486
11307
  if (!innerUid) {
10487
11308
  (0, import_errors.throwConflict)(
10488
11309
  `flowSurfaces configure field wrapper '${current == null ? void 0 : current.use}' cannot resolve inner field`,
@@ -10495,7 +11316,7 @@ class FlowSurfacesService {
10495
11316
  uid: innerUid
10496
11317
  },
10497
11318
  props: {
10498
- titleField: syncedTitleField
11319
+ titleField: effectiveSyncedTitleField
10499
11320
  }
10500
11321
  },
10501
11322
  options
@@ -10563,6 +11384,7 @@ class FlowSurfacesService {
10563
11384
  });
10564
11385
  const shouldSyncTitleField = titleFieldSyncDecision.shouldSync;
10565
11386
  const syncedTitleField = titleFieldSyncDecision.titleField;
11387
+ const canSyncInnerTitleField = this.supportsFieldTitleFieldProp(current == null ? void 0 : current.use);
10566
11388
  if ((parentWrapper == null ? void 0 : parentWrapper.uid) && canSyncWrapperTitleField && shouldSyncTitleField) {
10567
11389
  await this.updateSettings(
10568
11390
  {
@@ -10625,7 +11447,7 @@ class FlowSurfacesService {
10625
11447
  quickCreate: changes.quickCreate,
10626
11448
  displayStyle: changes.displayStyle,
10627
11449
  options: changes.options,
10628
- ...shouldSyncTitleField ? { titleField: syncedTitleField } : {},
11450
+ ...shouldSyncTitleField && canSyncInnerTitleField ? { titleField: syncedTitleField } : {},
10629
11451
  ...(0, import_service_utils.hasOwnDefined)(changes, "clickToOpen") || !import_lodash.default.isUndefined(changes.openView) ? { clickToOpen: effectiveClickToOpen } : {}
10630
11452
  }),
10631
11453
  stepParams: (0, import_service_utils.buildDefinedPayload)({
@@ -10692,6 +11514,7 @@ class FlowSurfacesService {
10692
11514
  return import_lodash.default.cloneDeep(value);
10693
11515
  }
10694
11516
  async configureActionNode(target, use, changes, options) {
11517
+ changes = await this.normalizeActionPanelActionChanges(changes, options);
10695
11518
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)(use);
10696
11519
  (0, import_service_utils.assertSupportedSimpleChanges)("action", changes, allowedKeys);
10697
11520
  const normalizedDefaultFilter = (0, import_service_utils.hasOwnDefined)(changes, "defaultFilter") ? this.normalizeFilterActionDefaultFilterValue(changes.defaultFilter) : void 0;
@@ -10914,6 +11737,21 @@ class FlowSurfacesService {
10914
11737
  }
10915
11738
  );
10916
11739
  }
11740
+ async normalizeActionPanelActionChanges(changes, options) {
11741
+ var _a;
11742
+ if (!(0, import_service_utils.hasOwnDefined)(changes, "type") || !((_a = options.current) == null ? void 0 : _a.uid)) {
11743
+ return changes;
11744
+ }
11745
+ const parentUid = options.current.parentId || await this.locator.findParentUid(options.current.uid, options.transaction);
11746
+ const parentNode = parentUid ? await this.repository.findModelById(parentUid, {
11747
+ transaction: options.transaction,
11748
+ includeAsyncNode: true
11749
+ }) : null;
11750
+ if ((parentNode == null ? void 0 : parentNode.use) !== "ActionPanelBlockModel") {
11751
+ return changes;
11752
+ }
11753
+ return import_lodash.default.omit(changes, ["type"]);
11754
+ }
10917
11755
  async buildFieldCatalog(target, options = {}) {
10918
11756
  const resolved = await this.locator.resolve(target, { transaction: options.transaction });
10919
11757
  const container = await this.surfaceContext.resolveFieldContainer(resolved.uid, options.transaction).catch(() => null);
@@ -11071,7 +11909,7 @@ class FlowSurfacesService {
11071
11909
  continue;
11072
11910
  }
11073
11911
  const fieldInterface = String((0, import_service_helpers.getFieldInterface)(field) || "").trim();
11074
- if (import_field_semantics.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
11912
+ if (import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(fieldInterface)) {
11075
11913
  continue;
11076
11914
  }
11077
11915
  const associationFieldName = (0, import_service_helpers.getFieldName)(field);
@@ -11869,30 +12707,436 @@ class FlowSurfacesService {
11869
12707
  const dataSource = (_a = dataSourceManager == null ? void 0 : dataSourceManager.get) == null ? void 0 : _a.call(dataSourceManager, normalizedDataSourceKey);
11870
12708
  return ((_c = (_b = dataSource == null ? void 0 : dataSource.collectionManager) == null ? void 0 : _b.getCollection) == null ? void 0 : _c.call(_b, collectionName)) || ((_e = (_d = this.plugin.app.db) == null ? void 0 : _d.getCollection) == null ? void 0 : _e.call(_d, collectionName));
11871
12709
  }
11872
- normalizeCalendarFieldPathInput(value, context, options = {}) {
12710
+ normalizeKanbanFieldNameInput(value, context, options = {}) {
11873
12711
  if (import_lodash.default.isUndefined(value)) {
11874
12712
  return void 0;
11875
12713
  }
11876
12714
  if (import_lodash.default.isNull(value) || value === "") {
11877
- if (options.allowEmpty) {
11878
- return "";
11879
- }
11880
- (0, import_errors.throwBadRequest)(`${context} is required`);
12715
+ return options.allowEmpty ? "" : void 0;
11881
12716
  }
11882
- const normalized = Array.isArray(value) ? value.map((item) => String(item || "").trim()).filter(Boolean).join(".") : String(value || "").trim();
11883
- if (!normalized && !options.allowEmpty) {
11884
- (0, import_errors.throwBadRequest)(`${context} is required`);
12717
+ const normalized = String(value || "").trim();
12718
+ if (!normalized) {
12719
+ return options.allowEmpty ? "" : void 0;
11885
12720
  }
11886
12721
  return normalized;
11887
12722
  }
11888
- isCalendarDateField(field) {
11889
- var _a, _b, _c;
11890
- const supportedTypes = new Set(this.getCalendarDateFieldTypes());
11891
- const candidates = [
11892
- (0, import_service_helpers.getFieldInterface)(field),
11893
- (0, import_service_helpers.getFieldType)(field),
11894
- (_a = field == null ? void 0 : field.uiSchema) == null ? void 0 : _a.type,
11895
- (_c = (_b = field == null ? void 0 : field.options) == null ? void 0 : _b.uiSchema) == null ? void 0 : _c.type
12723
+ getKanbanCollectionFilterTargetKey(collection) {
12724
+ var _a;
12725
+ const filterTargetKey = (collection == null ? void 0 : collection.filterTargetKey) || ((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.filterTargetKey);
12726
+ if (Array.isArray(filterTargetKey)) {
12727
+ return filterTargetKey.length === 1 ? String(filterTargetKey[0] || "").trim() || void 0 : void 0;
12728
+ }
12729
+ return typeof filterTargetKey === "string" ? filterTargetKey.trim() || void 0 : void 0;
12730
+ }
12731
+ isKanbanMultipleGroupField(field) {
12732
+ return (/* @__PURE__ */ new Set(["m2m", "o2m", "mbm"])).has(String((0, import_service_helpers.getFieldInterface)(field) || "").trim());
12733
+ }
12734
+ isKanbanAssociationGroupField(field) {
12735
+ return String((0, import_service_helpers.getFieldInterface)(field) || "").trim() === "m2o";
12736
+ }
12737
+ isKanbanGroupField(field) {
12738
+ const fieldInterface = String((0, import_service_helpers.getFieldInterface)(field) || "").trim();
12739
+ return (fieldInterface === "select" || fieldInterface === "m2o") && !this.isKanbanMultipleGroupField(field);
12740
+ }
12741
+ getKanbanGroupFieldCandidates(collection) {
12742
+ return (0, import_service_helpers.getCollectionFields)(collection).filter((field) => this.isKanbanGroupField(field) && (0, import_service_helpers.getFieldName)(field));
12743
+ }
12744
+ getKanbanDefaultGroupFieldName(collection) {
12745
+ return this.getKanbanGroupFieldCandidates(collection).map((field) => (0, import_service_helpers.getFieldName)(field)).find(Boolean);
12746
+ }
12747
+ getKanbanGroupField(collection, fieldName) {
12748
+ const normalizedFieldName = String(fieldName || "").trim();
12749
+ if (!normalizedFieldName) {
12750
+ return void 0;
12751
+ }
12752
+ return (0, import_service_helpers.getCollectionFields)(collection).find((field) => (0, import_service_helpers.getFieldName)(field) === normalizedFieldName);
12753
+ }
12754
+ getKanbanCollectionOrThrow(actionName, resourceInit) {
12755
+ const dataSourceKey = String((resourceInit == null ? void 0 : resourceInit.dataSourceKey) || "main").trim() || "main";
12756
+ const collectionName = String((resourceInit == null ? void 0 : resourceInit.collectionName) || "").trim();
12757
+ if (!collectionName) {
12758
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} kanban block requires resource.collectionName`);
12759
+ }
12760
+ const collection = this.getCollection(dataSourceKey, collectionName);
12761
+ if (!collection) {
12762
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} kanban collection '${dataSourceKey}.${collectionName}' not found`);
12763
+ }
12764
+ return {
12765
+ dataSourceKey,
12766
+ collectionName,
12767
+ collection
12768
+ };
12769
+ }
12770
+ assertKanbanCollectionCompatible(actionName, resourceInit) {
12771
+ const resolved = this.getKanbanCollectionOrThrow(actionName, resourceInit);
12772
+ const filterTargetKey = this.getKanbanCollectionFilterTargetKey(resolved.collection);
12773
+ if (!filterTargetKey) {
12774
+ (0, import_errors.throwBadRequest)(
12775
+ `flowSurfaces ${actionName} kanban collection '${resolved.dataSourceKey}.${resolved.collectionName}' must declare filterTargetKey`
12776
+ );
12777
+ }
12778
+ const groupFieldCandidates = this.getKanbanGroupFieldCandidates(resolved.collection);
12779
+ if (!groupFieldCandidates.length) {
12780
+ (0, import_errors.throwBadRequest)(
12781
+ `flowSurfaces ${actionName} kanban collection '${resolved.dataSourceKey}.${resolved.collectionName}' must contain at least one supported grouping field`
12782
+ );
12783
+ }
12784
+ return {
12785
+ ...resolved,
12786
+ filterTargetKey,
12787
+ groupFieldCandidates
12788
+ };
12789
+ }
12790
+ getKanbanRelationTargetCollection(groupField, dataSourceKey) {
12791
+ if (!this.isKanbanAssociationGroupField(groupField)) {
12792
+ return null;
12793
+ }
12794
+ return (0, import_service_helpers.resolveFieldTargetCollection)(
12795
+ groupField,
12796
+ dataSourceKey,
12797
+ (nextDataSourceKey, collectionName) => this.getCollection(nextDataSourceKey, collectionName)
12798
+ );
12799
+ }
12800
+ getKanbanRelationFieldCandidateNames(groupField, dataSourceKey) {
12801
+ const targetCollection = this.getKanbanRelationTargetCollection(groupField, dataSourceKey);
12802
+ if (!targetCollection) {
12803
+ return [];
12804
+ }
12805
+ return (0, import_service_helpers.getCollectionFields)(targetCollection).map((field) => (0, import_service_helpers.getFieldName)(field)).filter(Boolean);
12806
+ }
12807
+ getKanbanDefaultRelationTitleFieldName(groupField, dataSourceKey) {
12808
+ var _a;
12809
+ const targetCollection = this.getKanbanRelationTargetCollection(groupField, dataSourceKey);
12810
+ if (!targetCollection) {
12811
+ return void 0;
12812
+ }
12813
+ return (targetCollection == null ? void 0 : targetCollection.titleField) || ((_a = targetCollection == null ? void 0 : targetCollection.titleCollectionField) == null ? void 0 : _a.name) || this.getKanbanCollectionFilterTargetKey(targetCollection);
12814
+ }
12815
+ assertKanbanRelationFieldBinding(input) {
12816
+ const normalizedFieldName = String(input.fieldName || "").trim();
12817
+ if (!normalizedFieldName) {
12818
+ return;
12819
+ }
12820
+ const targetCollection = this.getKanbanRelationTargetCollection(input.groupField, input.dataSourceKey);
12821
+ if (!targetCollection) {
12822
+ (0, import_errors.throwBadRequest)(
12823
+ `flowSurfaces ${input.actionName} kanban ${input.kind} is only supported when groupField targets a relation`
12824
+ );
12825
+ }
12826
+ const field = (0, import_service_helpers.resolveFieldFromCollection)(targetCollection, normalizedFieldName);
12827
+ if (!field) {
12828
+ (0, import_errors.throwBadRequest)(
12829
+ `flowSurfaces ${input.actionName} kanban ${input.kind} '${normalizedFieldName}' does not exist in relation target collection for '${input.collectionName}'`
12830
+ );
12831
+ }
12832
+ }
12833
+ getKanbanGroupFieldSortScopeKeys(groupField) {
12834
+ const groupFieldName = (0, import_service_helpers.getFieldName)(groupField);
12835
+ if (!groupFieldName) {
12836
+ return [];
12837
+ }
12838
+ if (!this.isKanbanAssociationGroupField(groupField) || !(groupField == null ? void 0 : groupField.foreignKey)) {
12839
+ return [groupFieldName];
12840
+ }
12841
+ return [...new Set([groupField.foreignKey, groupFieldName].filter(Boolean))];
12842
+ }
12843
+ getKanbanCompatibleSortFieldNames(collection, groupField) {
12844
+ const scopeKeys = new Set(this.getKanbanGroupFieldSortScopeKeys(groupField));
12845
+ return (0, import_service_helpers.getCollectionFields)(collection).filter((field) => String((0, import_service_helpers.getFieldInterface)(field) || "").trim() === "sort").filter((field) => {
12846
+ var _a;
12847
+ return scopeKeys.has(String((field == null ? void 0 : field.scopeKey) || ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.scopeKey) || "").trim());
12848
+ }).map((field) => (0, import_service_helpers.getFieldName)(field)).filter(Boolean);
12849
+ }
12850
+ resolveKanbanCompatibleSortFieldName(input) {
12851
+ const normalizedRequested = this.normalizeKanbanFieldNameInput(input.requested, "", {
12852
+ allowEmpty: input.allowEmpty
12853
+ });
12854
+ if (import_lodash.default.isUndefined(normalizedRequested)) {
12855
+ return void 0;
12856
+ }
12857
+ if (!normalizedRequested) {
12858
+ return "";
12859
+ }
12860
+ const compatibleFieldNames = this.getKanbanCompatibleSortFieldNames(input.collection, input.groupField);
12861
+ if (!compatibleFieldNames.includes(normalizedRequested)) {
12862
+ (0, import_errors.throwBadRequest)(
12863
+ `flowSurfaces ${input.actionName} kanban dragSortBy '${normalizedRequested}' is not compatible with the current groupField`
12864
+ );
12865
+ }
12866
+ return normalizedRequested;
12867
+ }
12868
+ normalizeKanbanGroupOptions(value, context) {
12869
+ if (import_lodash.default.isUndefined(value)) {
12870
+ return void 0;
12871
+ }
12872
+ if (import_lodash.default.isNull(value)) {
12873
+ return [];
12874
+ }
12875
+ if (!Array.isArray(value)) {
12876
+ (0, import_errors.throwBadRequest)(`${context} must be an array`);
12877
+ }
12878
+ const seen = /* @__PURE__ */ new Set();
12879
+ return value.map((item, index) => {
12880
+ if (!import_lodash.default.isPlainObject(item)) {
12881
+ (0, import_errors.throwBadRequest)(`${context}[${index}] must be an object`);
12882
+ }
12883
+ const normalizedValue = String(item.value || "").trim();
12884
+ if (!normalizedValue) {
12885
+ (0, import_errors.throwBadRequest)(`${context}[${index}].value is required`);
12886
+ }
12887
+ if (seen.has(normalizedValue)) {
12888
+ (0, import_errors.throwBadRequest)(`${context}[${index}].value '${normalizedValue}' is duplicated`);
12889
+ }
12890
+ seen.add(normalizedValue);
12891
+ const label = typeof item.label === "string" ? item.label.trim() : typeof item.label === "number" || typeof item.label === "boolean" ? String(item.label) : normalizedValue;
12892
+ const color = typeof item.color === "string" ? item.color.trim() || void 0 : typeof item.color === "number" || typeof item.color === "boolean" ? String(item.color) : void 0;
12893
+ return (0, import_service_utils.buildDefinedPayload)({
12894
+ value: normalizedValue,
12895
+ label,
12896
+ color,
12897
+ ...item.isUnknown === true ? { isUnknown: true } : {}
12898
+ });
12899
+ });
12900
+ }
12901
+ buildKanbanInlineGroupOptions(groupField) {
12902
+ var _a, _b, _c;
12903
+ if (this.isKanbanAssociationGroupField(groupField)) {
12904
+ return void 0;
12905
+ }
12906
+ const enumOptions = ((_a = groupField == null ? void 0 : groupField.uiSchema) == null ? void 0 : _a.enum) || ((_c = (_b = groupField == null ? void 0 : groupField.options) == null ? void 0 : _b.uiSchema) == null ? void 0 : _c.enum);
12907
+ if (!Array.isArray(enumOptions)) {
12908
+ return void 0;
12909
+ }
12910
+ return this.normalizeKanbanGroupOptions(
12911
+ enumOptions.map((item) => {
12912
+ var _a2;
12913
+ return {
12914
+ value: item == null ? void 0 : item.value,
12915
+ label: (item == null ? void 0 : item.label) ?? (item == null ? void 0 : item.title) ?? ((_a2 = item == null ? void 0 : item.uiSchema) == null ? void 0 : _a2.title) ?? (item == null ? void 0 : item.name) ?? (item == null ? void 0 : item.value),
12916
+ color: item == null ? void 0 : item.color
12917
+ };
12918
+ }),
12919
+ "flowSurfaces kanban inline groupOptions"
12920
+ );
12921
+ }
12922
+ mergeKanbanInlineGroupOptions(inlineOptions, configuredOptions, context) {
12923
+ if (!(inlineOptions == null ? void 0 : inlineOptions.length)) {
12924
+ return configuredOptions;
12925
+ }
12926
+ if (!(configuredOptions == null ? void 0 : configuredOptions.length)) {
12927
+ return inlineOptions;
12928
+ }
12929
+ const inlineMap = new Map(inlineOptions.map((item) => [String(item.value), item]));
12930
+ configuredOptions.forEach((item) => {
12931
+ if (!inlineMap.has(String(item.value))) {
12932
+ (0, import_errors.throwBadRequest)(`${context} value '${item.value}' is not available on the current select groupField`);
12933
+ }
12934
+ });
12935
+ return configuredOptions.map((item) => {
12936
+ const inline = inlineMap.get(String(item.value));
12937
+ return (0, import_service_utils.buildDefinedPayload)({
12938
+ ...inline,
12939
+ ...item,
12940
+ label: item.label || (inline == null ? void 0 : inline.label) || String(item.value),
12941
+ color: item.color || (inline == null ? void 0 : inline.color)
12942
+ });
12943
+ });
12944
+ }
12945
+ normalizeKanbanPopupSettings(actionKey, popupSettings, blockUid) {
12946
+ const nextParams = import_lodash.default.cloneDeep(popupSettings || {});
12947
+ const actionUid = blockUid && actionKey ? this.getKanbanPopupActionUid(blockUid, actionKey) : void 0;
12948
+ const popupTemplateUidProvided = Object.prototype.hasOwnProperty.call(nextParams, "popupTemplateUid");
12949
+ const popupTemplateUid = typeof nextParams.popupTemplateUid === "string" ? nextParams.popupTemplateUid.trim() : nextParams.popupTemplateUid;
12950
+ if (popupTemplateUidProvided && (popupTemplateUid === void 0 || popupTemplateUid === null || popupTemplateUid === "")) {
12951
+ delete nextParams.popupTemplateUid;
12952
+ delete nextParams.popupTemplateContext;
12953
+ delete nextParams.popupTemplateHasFilterByTk;
12954
+ delete nextParams.popupTemplateHasSourceId;
12955
+ delete nextParams.uid;
12956
+ }
12957
+ const normalizedUid = typeof nextParams.uid === "string" ? nextParams.uid.trim() : nextParams.uid;
12958
+ if (!normalizedUid || normalizedUid === blockUid || normalizedUid === actionUid) {
12959
+ delete nextParams.uid;
12960
+ } else {
12961
+ nextParams.uid = normalizedUid;
12962
+ }
12963
+ if (typeof nextParams.mode === "string") {
12964
+ nextParams.mode = OPEN_VIEW_MODE_ALIASES[nextParams.mode] || nextParams.mode;
12965
+ }
12966
+ if (typeof nextParams.size === "string" && !nextParams.size.trim()) {
12967
+ delete nextParams.size;
12968
+ }
12969
+ if (typeof nextParams.pageModelClass === "string" && !nextParams.pageModelClass.trim()) {
12970
+ delete nextParams.pageModelClass;
12971
+ }
12972
+ return nextParams;
12973
+ }
12974
+ getKanbanPopupActionUse(actionKey) {
12975
+ return actionKey === "quickCreateAction" ? "KanbanQuickCreateActionModel" : "KanbanCardViewActionModel";
12976
+ }
12977
+ getKanbanPopupActionUid(kanbanUid, actionKey) {
12978
+ return `${kanbanUid}${KANBAN_POPUP_ACTION_UID_SUFFIX_BY_KEY[actionKey]}`;
12979
+ }
12980
+ getKanbanBlockResourceInit(blockNode) {
12981
+ const resourceInit = import_lodash.default.cloneDeep(import_lodash.default.get(blockNode, ["stepParams", "resourceSettings", "init"]) || {});
12982
+ if (resourceInit.collectionName && !resourceInit.dataSourceKey) {
12983
+ resourceInit.dataSourceKey = "main";
12984
+ }
12985
+ return resourceInit;
12986
+ }
12987
+ getKanbanPopupStoredSettings(blockNode, actionKey) {
12988
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
12989
+ const itemNode = (0, import_service_utils.getSingleNodeSubModel)((_a = blockNode == null ? void 0 : blockNode.subModels) == null ? void 0 : _a.item);
12990
+ const rawPopupSettings = actionKey === "quickCreateAction" ? import_lodash.default.get(blockNode, ["stepParams", "kanbanSettings", "popup"]) || {
12991
+ mode: (_b = blockNode == null ? void 0 : blockNode.props) == null ? void 0 : _b.popupMode,
12992
+ size: (_c = blockNode == null ? void 0 : blockNode.props) == null ? void 0 : _c.popupSize,
12993
+ popupTemplateUid: (_d = blockNode == null ? void 0 : blockNode.props) == null ? void 0 : _d.popupTemplateUid,
12994
+ pageModelClass: (_e = blockNode == null ? void 0 : blockNode.props) == null ? void 0 : _e.popupPageModelClass,
12995
+ uid: (_f = blockNode == null ? void 0 : blockNode.props) == null ? void 0 : _f.popupTargetUid
12996
+ } : import_lodash.default.get(itemNode, ["stepParams", "cardSettings", "popup"]) || {
12997
+ mode: (_g = itemNode == null ? void 0 : itemNode.props) == null ? void 0 : _g.openMode,
12998
+ size: (_h = itemNode == null ? void 0 : itemNode.props) == null ? void 0 : _h.popupSize,
12999
+ popupTemplateUid: (_i = itemNode == null ? void 0 : itemNode.props) == null ? void 0 : _i.popupTemplateUid,
13000
+ pageModelClass: (_j = itemNode == null ? void 0 : itemNode.props) == null ? void 0 : _j.pageModelClass,
13001
+ uid: (_k = itemNode == null ? void 0 : itemNode.props) == null ? void 0 : _k.popupTargetUid
13002
+ };
13003
+ return this.normalizeKanbanPopupSettings(actionKey, rawPopupSettings, blockNode == null ? void 0 : blockNode.uid);
13004
+ }
13005
+ buildKanbanPopupOpenView(input) {
13006
+ const actionUid = this.getKanbanPopupActionUid(input.blockNode.uid, input.actionKey);
13007
+ const resourceInit = input.resourceInit || this.getKanbanBlockResourceInit(input.blockNode);
13008
+ const defaults = (0, import_service_utils.buildDefinedPayload)({
13009
+ mode: "drawer",
13010
+ size: "medium",
13011
+ pageModelClass: "ChildPageModel",
13012
+ uid: actionUid,
13013
+ collectionName: resourceInit.collectionName,
13014
+ dataSourceKey: resourceInit.dataSourceKey || (resourceInit.collectionName ? "main" : void 0)
13015
+ });
13016
+ const current = this.getKanbanPopupStoredSettings(input.blockNode, input.actionKey);
13017
+ return (0, import_service_utils.buildDefinedPayload)({
13018
+ ...defaults,
13019
+ ...current,
13020
+ uid: current.uid || defaults.uid,
13021
+ collectionName: current.collectionName || defaults.collectionName,
13022
+ dataSourceKey: current.dataSourceKey || defaults.dataSourceKey
13023
+ });
13024
+ }
13025
+ async normalizeKanbanPopupConfigureValue(input) {
13026
+ if (import_lodash.default.isUndefined(input.value)) {
13027
+ return void 0;
13028
+ }
13029
+ if (import_lodash.default.isNull(input.value)) {
13030
+ return {};
13031
+ }
13032
+ const actionUid = this.getKanbanPopupActionUid(input.blockUid, input.actionKey);
13033
+ const normalized = await this.normalizeOpenView(input.actionName, input.value, {
13034
+ transaction: input.transaction,
13035
+ popupTemplateHostUid: actionUid,
13036
+ popupActionContext: {
13037
+ hasCurrentRecord: input.actionKey === "cardViewAction"
13038
+ }
13039
+ });
13040
+ return this.normalizeKanbanPopupSettings(input.actionKey, normalized || {}, input.blockUid);
13041
+ }
13042
+ buildKanbanInitialBlockProps(input) {
13043
+ const { collection, collectionName, dataSourceKey } = this.assertKanbanCollectionCompatible(
13044
+ input.actionName,
13045
+ input.resourceInit
13046
+ );
13047
+ const currentProps = import_lodash.default.cloneDeep(input.props || {});
13048
+ const defaultGroupFieldName = this.getKanbanDefaultGroupFieldName(collection);
13049
+ const nextGroupFieldName = String(currentProps.groupField || defaultGroupFieldName || "").trim();
13050
+ const nextGroupField = this.getKanbanGroupField(collection, nextGroupFieldName);
13051
+ if (!nextGroupField || !this.isKanbanGroupField(nextGroupField)) {
13052
+ (0, import_errors.throwBadRequest)(
13053
+ `flowSurfaces ${input.actionName} kanban collection '${dataSourceKey}.${collectionName}' must resolve a supported groupField`
13054
+ );
13055
+ }
13056
+ const configuredInlineGroupOptions = this.normalizeKanbanGroupOptions(
13057
+ currentProps.groupOptions,
13058
+ `flowSurfaces ${input.actionName} kanban groupOptions`
13059
+ );
13060
+ const inlineGroupOptions = this.buildKanbanInlineGroupOptions(nextGroupField);
13061
+ const nextGroupOptions = this.mergeKanbanInlineGroupOptions(
13062
+ inlineGroupOptions,
13063
+ configuredInlineGroupOptions,
13064
+ `flowSurfaces ${input.actionName} kanban groupOptions`
13065
+ );
13066
+ const nextDragSortBy = this.resolveKanbanCompatibleSortFieldName({
13067
+ actionName: input.actionName,
13068
+ collection,
13069
+ groupField: nextGroupField,
13070
+ requested: currentProps.dragSortBy,
13071
+ allowEmpty: true
13072
+ });
13073
+ const nextDragEnabled = currentProps.dragEnabled === true && !!nextDragSortBy;
13074
+ const nextGroupTitleField = this.isKanbanAssociationGroupField(nextGroupField) ? this.normalizeKanbanFieldNameInput(
13075
+ currentProps.groupTitleField || this.getKanbanDefaultRelationTitleFieldName(nextGroupField, dataSourceKey),
13076
+ `flowSurfaces ${input.actionName} kanban groupTitleField`,
13077
+ { allowEmpty: true }
13078
+ ) || void 0 : void 0;
13079
+ const nextGroupColorField = this.isKanbanAssociationGroupField(nextGroupField) ? this.normalizeKanbanFieldNameInput(
13080
+ currentProps.groupColorField,
13081
+ `flowSurfaces ${input.actionName} kanban groupColorField`,
13082
+ { allowEmpty: true }
13083
+ ) || void 0 : void 0;
13084
+ if (nextGroupTitleField) {
13085
+ this.assertKanbanRelationFieldBinding({
13086
+ actionName: input.actionName,
13087
+ collectionName,
13088
+ dataSourceKey,
13089
+ groupField: nextGroupField,
13090
+ fieldName: nextGroupTitleField,
13091
+ kind: "groupTitleField"
13092
+ });
13093
+ }
13094
+ if (nextGroupColorField) {
13095
+ this.assertKanbanRelationFieldBinding({
13096
+ actionName: input.actionName,
13097
+ collectionName,
13098
+ dataSourceKey,
13099
+ groupField: nextGroupField,
13100
+ fieldName: nextGroupColorField,
13101
+ kind: "groupColorField"
13102
+ });
13103
+ }
13104
+ return (0, import_service_utils.buildDefinedPayload)({
13105
+ ...currentProps,
13106
+ groupField: nextGroupFieldName,
13107
+ groupTitleField: nextGroupTitleField,
13108
+ groupColorField: nextGroupColorField,
13109
+ groupOptions: nextGroupOptions,
13110
+ styleVariant: currentProps.styleVariant || "color",
13111
+ quickCreateEnabled: currentProps.quickCreateEnabled === true,
13112
+ dragEnabled: nextDragEnabled,
13113
+ dragSortBy: nextDragSortBy || void 0
13114
+ });
13115
+ }
13116
+ normalizeCalendarFieldPathInput(value, context, options = {}) {
13117
+ if (import_lodash.default.isUndefined(value)) {
13118
+ return void 0;
13119
+ }
13120
+ if (import_lodash.default.isNull(value) || value === "") {
13121
+ if (options.allowEmpty) {
13122
+ return "";
13123
+ }
13124
+ (0, import_errors.throwBadRequest)(`${context} is required`);
13125
+ }
13126
+ const normalized = Array.isArray(value) ? value.map((item) => String(item || "").trim()).filter(Boolean).join(".") : String(value || "").trim();
13127
+ if (!normalized && !options.allowEmpty) {
13128
+ (0, import_errors.throwBadRequest)(`${context} is required`);
13129
+ }
13130
+ return normalized;
13131
+ }
13132
+ isCalendarDateField(field) {
13133
+ var _a, _b, _c;
13134
+ const supportedTypes = new Set(this.getCalendarDateFieldTypes());
13135
+ const candidates = [
13136
+ (0, import_service_helpers.getFieldInterface)(field),
13137
+ (0, import_service_helpers.getFieldType)(field),
13138
+ (_a = field == null ? void 0 : field.uiSchema) == null ? void 0 : _a.type,
13139
+ (_c = (_b = field == null ? void 0 : field.options) == null ? void 0 : _b.uiSchema) == null ? void 0 : _c.type
11896
13140
  ].filter(Boolean);
11897
13141
  return candidates.some((item) => supportedTypes.has(String(item)));
11898
13142
  }
@@ -12094,14 +13338,17 @@ class FlowSurfacesService {
12094
13338
  delete nextParams.uid;
12095
13339
  }
12096
13340
  if (actionKey === "quickCreateAction") {
12097
- if (nextParams.popupTemplateHasFilterByTk) {
13341
+ const hasRecordScopedTemplate = !!nextParams.popupTemplateHasFilterByTk || !!nextParams.popupTemplateHasSourceId || !import_lodash.default.isUndefined(nextParams.filterByTk) || !import_lodash.default.isUndefined(nextParams.sourceId) || !!String(nextParams.associationName || "").trim();
13342
+ if (hasRecordScopedTemplate) {
12098
13343
  delete nextParams.popupTemplateUid;
12099
13344
  delete nextParams.popupTemplateContext;
12100
13345
  delete nextParams.popupTemplateHasFilterByTk;
12101
13346
  delete nextParams.popupTemplateHasSourceId;
12102
13347
  delete nextParams.uid;
12103
13348
  }
13349
+ delete nextParams.associationName;
12104
13350
  delete nextParams.filterByTk;
13351
+ delete nextParams.sourceId;
12105
13352
  }
12106
13353
  return nextParams;
12107
13354
  }
@@ -12210,7 +13457,280 @@ class FlowSurfacesService {
12210
13457
  await this.reconcilePopupOpenViewTransition(expectedUid, currentOpenView, openView, transaction);
12211
13458
  }
12212
13459
  const nextActionNode = {
12213
- ...(existing == null ? void 0 : existing.uid) && existing.uid === expectedUid ? import_lodash.default.cloneDeep(existing) : {},
13460
+ ...(existing == null ? void 0 : existing.uid) && existing.uid === expectedUid ? import_lodash.default.cloneDeep(existing) : {},
13461
+ uid: expectedUid,
13462
+ use: expectedUse,
13463
+ stepParams: import_lodash.default.merge({}, (existing == null ? void 0 : existing.uid) === expectedUid ? import_lodash.default.cloneDeep(existing.stepParams || {}) : {}, {
13464
+ popupSettings: {
13465
+ openView
13466
+ }
13467
+ })
13468
+ };
13469
+ await this.repository.upsertModel(
13470
+ {
13471
+ parentId: blockNode.uid,
13472
+ subKey: actionKey,
13473
+ subType: "object",
13474
+ ...nextActionNode
13475
+ },
13476
+ { transaction }
13477
+ );
13478
+ changed = true;
13479
+ }
13480
+ if (!changed) {
13481
+ return blockNode;
13482
+ }
13483
+ return this.repository.findModelById(blockNode.uid, {
13484
+ transaction,
13485
+ includeAsyncNode: true
13486
+ });
13487
+ }
13488
+ async ensureCalendarBlockPopupHostsInTree(node, transaction) {
13489
+ if (!node || typeof node !== "object") {
13490
+ return node;
13491
+ }
13492
+ let current = node;
13493
+ if (current.use === "CalendarBlockModel") {
13494
+ current = await this.ensureCalendarBlockPopupHosts(current, transaction);
13495
+ }
13496
+ for (const [subKey, value] of Object.entries(current.subModels || {})) {
13497
+ if (Array.isArray(value)) {
13498
+ const nextItems = [];
13499
+ let changed = false;
13500
+ for (const item of value) {
13501
+ const nextItem = await this.ensureCalendarBlockPopupHostsInTree(item, transaction);
13502
+ nextItems.push(nextItem);
13503
+ changed = changed || nextItem !== item;
13504
+ }
13505
+ if (changed) {
13506
+ current.subModels[subKey] = nextItems;
13507
+ }
13508
+ continue;
13509
+ }
13510
+ const nextValue = await this.ensureCalendarBlockPopupHostsInTree(value, transaction);
13511
+ if (nextValue !== value) {
13512
+ current.subModels[subKey] = nextValue;
13513
+ }
13514
+ }
13515
+ return current;
13516
+ }
13517
+ projectCalendarBlockPopupHosts(node) {
13518
+ var _a;
13519
+ if (!node || typeof node !== "object") {
13520
+ return node;
13521
+ }
13522
+ const current = node;
13523
+ if (!(current == null ? void 0 : current.uid) || current.use !== "CalendarBlockModel") {
13524
+ return node;
13525
+ }
13526
+ const resourceInit = this.getCalendarBlockResourceInit(current);
13527
+ let nextSubModels = current.subModels;
13528
+ let changed = false;
13529
+ for (const actionKey of CALENDAR_POPUP_ACTION_KEYS) {
13530
+ const existing = (0, import_service_utils.getSingleNodeSubModel)((_a = current.subModels) == null ? void 0 : _a[actionKey]);
13531
+ const expectedUid = this.getCalendarPopupActionUid(current.uid, actionKey);
13532
+ const expectedUse = this.getCalendarPopupActionUse(actionKey);
13533
+ const openView = this.buildCalendarPopupOpenView({
13534
+ blockNode: current,
13535
+ actionKey,
13536
+ resourceInit
13537
+ });
13538
+ const currentOpenView = this.resolvePopupHostOpenView(existing);
13539
+ if ((existing == null ? void 0 : existing.uid) === expectedUid && existing.use === expectedUse && import_lodash.default.isEqual(currentOpenView, openView)) {
13540
+ continue;
13541
+ }
13542
+ const nextActionNode = {
13543
+ ...(existing == null ? void 0 : existing.uid) === expectedUid ? import_lodash.default.cloneDeep(existing) : {},
13544
+ uid: expectedUid,
13545
+ use: expectedUse,
13546
+ stepParams: import_lodash.default.merge({}, (existing == null ? void 0 : existing.uid) === expectedUid ? import_lodash.default.cloneDeep(existing.stepParams || {}) : {}, {
13547
+ popupSettings: {
13548
+ openView
13549
+ }
13550
+ })
13551
+ };
13552
+ if (!changed) {
13553
+ nextSubModels = {
13554
+ ...current.subModels || {}
13555
+ };
13556
+ changed = true;
13557
+ }
13558
+ nextSubModels[actionKey] = nextActionNode;
13559
+ }
13560
+ if (!changed) {
13561
+ return node;
13562
+ }
13563
+ return {
13564
+ ...current,
13565
+ subModels: nextSubModels
13566
+ };
13567
+ }
13568
+ projectCalendarBlockPopupHostsInTree(node) {
13569
+ if (!node || typeof node !== "object") {
13570
+ return node;
13571
+ }
13572
+ let current = this.projectCalendarBlockPopupHosts(node);
13573
+ let nextSubModels = current == null ? void 0 : current.subModels;
13574
+ let changed = current !== node;
13575
+ if (!nextSubModels || typeof nextSubModels !== "object") {
13576
+ return current;
13577
+ }
13578
+ for (const [subKey, value] of Object.entries(nextSubModels)) {
13579
+ if (Array.isArray(value)) {
13580
+ const nextItems = [];
13581
+ let itemsChanged = false;
13582
+ for (const item of value) {
13583
+ const nextItem = this.projectCalendarBlockPopupHostsInTree(item);
13584
+ nextItems.push(nextItem);
13585
+ itemsChanged = itemsChanged || nextItem !== item;
13586
+ }
13587
+ if (!itemsChanged) {
13588
+ continue;
13589
+ }
13590
+ if (!changed) {
13591
+ current = {
13592
+ ...current,
13593
+ subModels: {
13594
+ ...nextSubModels
13595
+ }
13596
+ };
13597
+ nextSubModels = current.subModels;
13598
+ changed = true;
13599
+ }
13600
+ nextSubModels[subKey] = nextItems;
13601
+ continue;
13602
+ }
13603
+ const nextValue = this.projectCalendarBlockPopupHostsInTree(value);
13604
+ if (nextValue === value) {
13605
+ continue;
13606
+ }
13607
+ if (!changed) {
13608
+ current = {
13609
+ ...current,
13610
+ subModels: {
13611
+ ...nextSubModels
13612
+ }
13613
+ };
13614
+ nextSubModels = current.subModels;
13615
+ changed = true;
13616
+ }
13617
+ nextSubModels[subKey] = nextValue;
13618
+ }
13619
+ return current;
13620
+ }
13621
+ async ensureKanbanBlockPopupHosts(blockNode, transaction) {
13622
+ var _a;
13623
+ if (!(blockNode == null ? void 0 : blockNode.uid) || blockNode.use !== "KanbanBlockModel") {
13624
+ return blockNode;
13625
+ }
13626
+ const resourceInit = this.getKanbanBlockResourceInit(blockNode);
13627
+ let changed = false;
13628
+ for (const actionKey of KANBAN_POPUP_ACTION_KEYS) {
13629
+ const existing = (0, import_service_utils.getSingleNodeSubModel)((_a = blockNode.subModels) == null ? void 0 : _a[actionKey]);
13630
+ const expectedUid = this.getKanbanPopupActionUid(blockNode.uid, actionKey);
13631
+ const expectedUse = this.getKanbanPopupActionUse(actionKey);
13632
+ const openView = this.buildKanbanPopupOpenView({
13633
+ blockNode,
13634
+ actionKey,
13635
+ resourceInit
13636
+ });
13637
+ const currentOpenView = this.resolvePopupHostOpenView(existing);
13638
+ const shouldReplaceExisting = (existing == null ? void 0 : existing.uid) && existing.uid !== expectedUid;
13639
+ const shouldUpsert = !(existing == null ? void 0 : existing.uid) || shouldReplaceExisting || existing.use !== expectedUse || !import_lodash.default.isEqual(currentOpenView, openView);
13640
+ if (!shouldUpsert) {
13641
+ continue;
13642
+ }
13643
+ if (shouldReplaceExisting) {
13644
+ await this.removeNodeTreeWithBindings(existing.uid, transaction);
13645
+ }
13646
+ if ((existing == null ? void 0 : existing.uid) && existing.uid === expectedUid && !import_lodash.default.isEqual(currentOpenView, openView)) {
13647
+ await this.reconcilePopupOpenViewTransition(expectedUid, currentOpenView, openView, transaction);
13648
+ }
13649
+ const nextActionNode = {
13650
+ ...(existing == null ? void 0 : existing.uid) && existing.uid === expectedUid ? import_lodash.default.cloneDeep(existing) : {},
13651
+ uid: expectedUid,
13652
+ use: expectedUse,
13653
+ stepParams: import_lodash.default.merge({}, (existing == null ? void 0 : existing.uid) === expectedUid ? import_lodash.default.cloneDeep(existing.stepParams || {}) : {}, {
13654
+ popupSettings: {
13655
+ openView
13656
+ }
13657
+ })
13658
+ };
13659
+ await this.repository.upsertModel(
13660
+ {
13661
+ parentId: blockNode.uid,
13662
+ subKey: actionKey,
13663
+ subType: "object",
13664
+ ...nextActionNode
13665
+ },
13666
+ { transaction }
13667
+ );
13668
+ changed = true;
13669
+ }
13670
+ if (!changed) {
13671
+ return blockNode;
13672
+ }
13673
+ return this.repository.findModelById(blockNode.uid, {
13674
+ transaction,
13675
+ includeAsyncNode: true
13676
+ });
13677
+ }
13678
+ async ensureKanbanBlockPopupHostsInTree(node, transaction) {
13679
+ if (!node || typeof node !== "object") {
13680
+ return node;
13681
+ }
13682
+ let current = node;
13683
+ if (current.use === "KanbanBlockModel") {
13684
+ current = await this.ensureKanbanBlockPopupHosts(current, transaction);
13685
+ }
13686
+ for (const [subKey, value] of Object.entries(current.subModels || {})) {
13687
+ if (Array.isArray(value)) {
13688
+ const nextItems = [];
13689
+ let changed = false;
13690
+ for (const item of value) {
13691
+ const nextItem = await this.ensureKanbanBlockPopupHostsInTree(item, transaction);
13692
+ nextItems.push(nextItem);
13693
+ changed = changed || nextItem !== item;
13694
+ }
13695
+ if (changed) {
13696
+ current.subModels[subKey] = nextItems;
13697
+ }
13698
+ continue;
13699
+ }
13700
+ const nextValue = await this.ensureKanbanBlockPopupHostsInTree(value, transaction);
13701
+ if (nextValue !== value) {
13702
+ current.subModels[subKey] = nextValue;
13703
+ }
13704
+ }
13705
+ return current;
13706
+ }
13707
+ projectKanbanBlockPopupHosts(node) {
13708
+ var _a;
13709
+ if (!node || typeof node !== "object") {
13710
+ return node;
13711
+ }
13712
+ const current = node;
13713
+ if (!(current == null ? void 0 : current.uid) || current.use !== "KanbanBlockModel") {
13714
+ return node;
13715
+ }
13716
+ const resourceInit = this.getKanbanBlockResourceInit(current);
13717
+ let nextSubModels = current.subModels;
13718
+ let changed = false;
13719
+ for (const actionKey of KANBAN_POPUP_ACTION_KEYS) {
13720
+ const existing = (0, import_service_utils.getSingleNodeSubModel)((_a = current.subModels) == null ? void 0 : _a[actionKey]);
13721
+ const expectedUid = this.getKanbanPopupActionUid(current.uid, actionKey);
13722
+ const expectedUse = this.getKanbanPopupActionUse(actionKey);
13723
+ const openView = this.buildKanbanPopupOpenView({
13724
+ blockNode: current,
13725
+ actionKey,
13726
+ resourceInit
13727
+ });
13728
+ const currentOpenView = this.resolvePopupHostOpenView(existing);
13729
+ if ((existing == null ? void 0 : existing.uid) === expectedUid && existing.use === expectedUse && import_lodash.default.isEqual(currentOpenView, openView)) {
13730
+ continue;
13731
+ }
13732
+ const nextActionNode = {
13733
+ ...(existing == null ? void 0 : existing.uid) === expectedUid ? import_lodash.default.cloneDeep(existing) : {},
12214
13734
  uid: expectedUid,
12215
13735
  use: expectedUse,
12216
13736
  stepParams: import_lodash.default.merge({}, (existing == null ? void 0 : existing.uid) === expectedUid ? import_lodash.default.cloneDeep(existing.stepParams || {}) : {}, {
@@ -12219,54 +13739,100 @@ class FlowSurfacesService {
12219
13739
  }
12220
13740
  })
12221
13741
  };
12222
- await this.repository.upsertModel(
12223
- {
12224
- parentId: blockNode.uid,
12225
- subKey: actionKey,
12226
- subType: "object",
12227
- ...nextActionNode
12228
- },
12229
- { transaction }
12230
- );
12231
- changed = true;
13742
+ if (!changed) {
13743
+ nextSubModels = {
13744
+ ...current.subModels || {}
13745
+ };
13746
+ changed = true;
13747
+ }
13748
+ nextSubModels[actionKey] = nextActionNode;
12232
13749
  }
12233
13750
  if (!changed) {
12234
- return blockNode;
13751
+ return node;
12235
13752
  }
12236
- return this.repository.findModelById(blockNode.uid, {
12237
- transaction,
12238
- includeAsyncNode: true
12239
- });
13753
+ return {
13754
+ ...current,
13755
+ subModels: nextSubModels
13756
+ };
12240
13757
  }
12241
- async ensureCalendarBlockPopupHostsInTree(node, transaction) {
13758
+ projectKanbanBlockPopupHostsInTree(node) {
12242
13759
  if (!node || typeof node !== "object") {
12243
13760
  return node;
12244
13761
  }
12245
- const current = node;
12246
- if (current.use === "CalendarBlockModel") {
12247
- return await this.ensureCalendarBlockPopupHosts(current, transaction);
13762
+ let current = this.projectKanbanBlockPopupHosts(node);
13763
+ let nextSubModels = current == null ? void 0 : current.subModels;
13764
+ let changed = current !== node;
13765
+ if (!nextSubModels || typeof nextSubModels !== "object") {
13766
+ return current;
12248
13767
  }
12249
- for (const [subKey, value] of Object.entries(current.subModels || {})) {
13768
+ for (const [subKey, value] of Object.entries(nextSubModels)) {
12250
13769
  if (Array.isArray(value)) {
12251
13770
  const nextItems = [];
12252
- let changed = false;
13771
+ let itemsChanged = false;
12253
13772
  for (const item of value) {
12254
- const nextItem = await this.ensureCalendarBlockPopupHostsInTree(item, transaction);
13773
+ const nextItem = this.projectKanbanBlockPopupHostsInTree(item);
12255
13774
  nextItems.push(nextItem);
12256
- changed = changed || nextItem !== item;
13775
+ itemsChanged = itemsChanged || nextItem !== item;
12257
13776
  }
12258
- if (changed) {
12259
- current.subModels[subKey] = nextItems;
13777
+ if (!itemsChanged) {
13778
+ continue;
12260
13779
  }
13780
+ if (!changed) {
13781
+ current = {
13782
+ ...current,
13783
+ subModels: {
13784
+ ...nextSubModels
13785
+ }
13786
+ };
13787
+ nextSubModels = current.subModels;
13788
+ changed = true;
13789
+ }
13790
+ nextSubModels[subKey] = nextItems;
12261
13791
  continue;
12262
13792
  }
12263
- const nextValue = await this.ensureCalendarBlockPopupHostsInTree(value, transaction);
12264
- if (nextValue !== value) {
12265
- current.subModels[subKey] = nextValue;
13793
+ const nextValue = this.projectKanbanBlockPopupHostsInTree(value);
13794
+ if (nextValue === value) {
13795
+ continue;
13796
+ }
13797
+ if (!changed) {
13798
+ current = {
13799
+ ...current,
13800
+ subModels: {
13801
+ ...nextSubModels
13802
+ }
13803
+ };
13804
+ nextSubModels = current.subModels;
13805
+ changed = true;
12266
13806
  }
13807
+ nextSubModels[subKey] = nextValue;
12267
13808
  }
12268
13809
  return current;
12269
13810
  }
13811
+ getCalendarSettingValue(node, propKey, stepParamsPath) {
13812
+ if (import_lodash.default.has(node, ["props", propKey])) {
13813
+ return import_lodash.default.get(node, ["props", propKey]);
13814
+ }
13815
+ return import_lodash.default.get(node, ["stepParams", ...stepParamsPath]);
13816
+ }
13817
+ validateCalendarSettingValues(actionName, values) {
13818
+ if (!import_lodash.default.isUndefined(values.defaultView)) {
13819
+ const defaultView = typeof values.defaultView === "string" ? values.defaultView.trim() : String(values.defaultView || "").trim();
13820
+ if (!CALENDAR_DEFAULT_VIEWS.has(defaultView)) {
13821
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} calendar defaultView must be one of: month, week, day`);
13822
+ }
13823
+ }
13824
+ if (!import_lodash.default.isUndefined(values.quickCreateEvent) && !import_lodash.default.isBoolean(values.quickCreateEvent)) {
13825
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} calendar quickCreateEvent must be a boolean`);
13826
+ }
13827
+ if (!import_lodash.default.isUndefined(values.showLunar) && !import_lodash.default.isBoolean(values.showLunar)) {
13828
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} calendar showLunar must be a boolean`);
13829
+ }
13830
+ if (!import_lodash.default.isUndefined(values.weekStart)) {
13831
+ if (!Number.isInteger(values.weekStart) || !CALENDAR_WEEK_STARTS.has(values.weekStart)) {
13832
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} calendar weekStart must be 0 or 1`);
13833
+ }
13834
+ }
13835
+ }
12270
13836
  validateCalendarBlockState(actionName, node) {
12271
13837
  var _a;
12272
13838
  if ((node == null ? void 0 : node.use) !== "CalendarBlockModel") {
@@ -12303,6 +13869,79 @@ class FlowSurfacesService {
12303
13869
  kind
12304
13870
  });
12305
13871
  }
13872
+ this.validateCalendarSettingValues(actionName, {
13873
+ defaultView: this.getCalendarSettingValue(node, "defaultView", [
13874
+ "calendarSettings",
13875
+ "defaultView",
13876
+ "defaultView"
13877
+ ]),
13878
+ quickCreateEvent: this.getCalendarSettingValue(node, "enableQuickCreateEvent", [
13879
+ "calendarSettings",
13880
+ "quickCreateEvent",
13881
+ "enableQuickCreateEvent"
13882
+ ]),
13883
+ showLunar: this.getCalendarSettingValue(node, "showLunar", ["calendarSettings", "showLunar", "showLunar"]),
13884
+ weekStart: this.getCalendarSettingValue(node, "weekStart", ["calendarSettings", "weekStart", "weekStart"])
13885
+ });
13886
+ }
13887
+ validateKanbanBlockState(actionName, node) {
13888
+ var _a, _b, _c, _d, _e;
13889
+ if ((node == null ? void 0 : node.use) !== "KanbanBlockModel") {
13890
+ return;
13891
+ }
13892
+ const resourceInit = this.getKanbanBlockResourceInit(node);
13893
+ const { collection, collectionName, dataSourceKey } = this.assertKanbanCollectionCompatible(
13894
+ actionName,
13895
+ resourceInit
13896
+ );
13897
+ const groupFieldName = String(((_a = node == null ? void 0 : node.props) == null ? void 0 : _a.groupField) || this.getKanbanDefaultGroupFieldName(collection) || "").trim() || void 0;
13898
+ const groupField = this.getKanbanGroupField(collection, groupFieldName);
13899
+ if (!groupField || !this.isKanbanGroupField(groupField)) {
13900
+ (0, import_errors.throwBadRequest)(
13901
+ `flowSurfaces ${actionName} kanban groupField '${groupFieldName || ""}' is not supported by KanbanBlockModel`
13902
+ );
13903
+ }
13904
+ if (this.isKanbanAssociationGroupField(groupField)) {
13905
+ const groupTitleField = this.normalizeKanbanFieldNameInput((_b = node == null ? void 0 : node.props) == null ? void 0 : _b.groupTitleField, "", { allowEmpty: true }) || void 0;
13906
+ const groupColorField = this.normalizeKanbanFieldNameInput((_c = node == null ? void 0 : node.props) == null ? void 0 : _c.groupColorField, "", { allowEmpty: true }) || void 0;
13907
+ if (groupTitleField) {
13908
+ this.assertKanbanRelationFieldBinding({
13909
+ actionName,
13910
+ collectionName,
13911
+ dataSourceKey,
13912
+ groupField,
13913
+ fieldName: groupTitleField,
13914
+ kind: "groupTitleField"
13915
+ });
13916
+ }
13917
+ if (groupColorField) {
13918
+ this.assertKanbanRelationFieldBinding({
13919
+ actionName,
13920
+ collectionName,
13921
+ dataSourceKey,
13922
+ groupField,
13923
+ fieldName: groupColorField,
13924
+ kind: "groupColorField"
13925
+ });
13926
+ }
13927
+ }
13928
+ const inlineGroupOptions = this.buildKanbanInlineGroupOptions(groupField);
13929
+ if (Array.isArray((_d = node == null ? void 0 : node.props) == null ? void 0 : _d.groupOptions)) {
13930
+ this.mergeKanbanInlineGroupOptions(
13931
+ inlineGroupOptions,
13932
+ import_lodash.default.cloneDeep(node.props.groupOptions),
13933
+ `flowSurfaces ${actionName} kanban groupOptions`
13934
+ );
13935
+ }
13936
+ if ((_e = node == null ? void 0 : node.props) == null ? void 0 : _e.dragSortBy) {
13937
+ this.resolveKanbanCompatibleSortFieldName({
13938
+ actionName,
13939
+ collection,
13940
+ groupField,
13941
+ requested: node.props.dragSortBy,
13942
+ allowEmpty: true
13943
+ });
13944
+ }
12306
13945
  }
12307
13946
  async resolveFieldDefinition(input) {
12308
13947
  const collection = this.getCollection(input.dataSourceKey, input.collectionName);
@@ -12468,6 +14107,19 @@ class FlowSurfacesService {
12468
14107
  );
12469
14108
  return (0, import_service_helpers.resolveFieldFromCollection)(targetCollection, titleFieldName) || input.field;
12470
14109
  }
14110
+ supportsFieldTitleFieldProp(use) {
14111
+ return (0, import_configure_options.getConfigureOptionKeysForUse)(use).includes("titleField");
14112
+ }
14113
+ normalizeFieldPropsForUse(use, props) {
14114
+ const normalizedProps = import_lodash.default.cloneDeep(props || {});
14115
+ if (this.supportsFieldTitleFieldProp(use)) {
14116
+ return normalizedProps;
14117
+ }
14118
+ if (Object.prototype.hasOwnProperty.call(normalizedProps, "titleField")) {
14119
+ delete normalizedProps.titleField;
14120
+ }
14121
+ return normalizedProps;
14122
+ }
12471
14123
  async ensureGridChild(parentUid, use, transaction) {
12472
14124
  const existing = await this.repository.findModelByParentId(parentUid, {
12473
14125
  transaction,
@@ -12647,7 +14299,7 @@ class FlowSurfacesService {
12647
14299
  );
12648
14300
  const associationInterface = (0, import_service_helpers.getFieldInterface)(parsed.associationField);
12649
14301
  const leafField = (0, import_service_helpers.resolveFieldFromCollection)(parsed.leafCollection, parsed.leafFieldPath);
12650
- const shouldBindAssociationValue = DISPLAY_FIELD_WRAPPER_USES.has(input.wrapperUse || "") && !!parsed.associationPathName && parsed.fieldPath !== parsed.associationPathName && import_field_semantics.MULTI_VALUE_ASSOCIATION_INTERFACES.has(associationInterface || "");
14302
+ const shouldBindAssociationValue = DISPLAY_FIELD_WRAPPER_USES.has(input.wrapperUse || "") && !!parsed.associationPathName && parsed.fieldPath !== parsed.associationPathName && import_association_interfaces.MULTI_VALUE_ASSOCIATION_INTERFACES.has(associationInterface || "");
12651
14303
  if (shouldBindAssociationValue) {
12652
14304
  const associationFieldPath = parsed.associationPathName;
12653
14305
  if (!associationFieldPath) {
@@ -12689,6 +14341,357 @@ class FlowSurfacesService {
12689
14341
  usesAssociationValueBinding: false
12690
14342
  };
12691
14343
  }
14344
+ getCollectionFieldOrBadRequest(collection, fieldPath, context) {
14345
+ const field = (0, import_service_helpers.resolveFieldFromCollection)(collection, fieldPath);
14346
+ if (!field) {
14347
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${context} field '${fieldPath}' does not exist on relation target collection`);
14348
+ }
14349
+ return field;
14350
+ }
14351
+ buildRelationTargetFieldInit(collection, fieldPath) {
14352
+ return (0, import_service_utils.buildDefinedPayload)({
14353
+ dataSourceKey: (collection == null ? void 0 : collection.dataSourceKey) || "main",
14354
+ collectionName: (0, import_service_helpers.getCollectionName)(collection),
14355
+ fieldPath
14356
+ });
14357
+ }
14358
+ buildRelationTargetTableColumnNode(input) {
14359
+ const field = this.getCollectionFieldOrBadRequest(input.collection, input.fieldPath, "fieldType.fields");
14360
+ const fieldUse = input.columnUse === "SubTableColumnModel" ? (0, import_service_helpers.inferFieldMenuEditableFieldUse)((0, import_service_helpers.getFieldInterface)(field)) || "InputFieldModel" : (0, import_service_helpers.inferAssociationLeafDisplayFieldUse)((0, import_service_helpers.getFieldInterface)(field)) || "DisplayTextFieldModel";
14361
+ const title = (0, import_service_helpers.getFieldTitle)(field);
14362
+ const fieldInit = this.buildRelationTargetFieldInit(input.collection, input.fieldPath);
14363
+ return {
14364
+ uid: (0, import_utils.uid)(),
14365
+ use: input.columnUse,
14366
+ props: (0, import_service_utils.buildDefinedPayload)({
14367
+ title,
14368
+ dataIndex: (0, import_service_helpers.getFieldName)(field)
14369
+ }),
14370
+ stepParams: {
14371
+ fieldSettings: {
14372
+ init: fieldInit
14373
+ },
14374
+ ...input.columnUse === "TableColumnModel" ? {
14375
+ tableColumnSettings: {
14376
+ title: {
14377
+ title
14378
+ }
14379
+ }
14380
+ } : {}
14381
+ },
14382
+ subModels: {
14383
+ field: {
14384
+ uid: (0, import_utils.uid)(),
14385
+ use: fieldUse,
14386
+ props: this.normalizeFieldPropsForUse(
14387
+ fieldUse,
14388
+ (0, import_service_utils.getFieldBindingDefaultProps)("TableColumnModel", fieldUse, field)
14389
+ ),
14390
+ stepParams: {
14391
+ fieldSettings: {
14392
+ init: fieldInit
14393
+ },
14394
+ fieldBinding: {
14395
+ use: fieldUse
14396
+ }
14397
+ }
14398
+ }
14399
+ }
14400
+ };
14401
+ }
14402
+ buildRelationTargetGridItemNode(input) {
14403
+ const field = this.getCollectionFieldOrBadRequest(input.collection, input.fieldPath, "fieldType.fields");
14404
+ const fieldUse = input.wrapperUse === "FormItemModel" ? (0, import_service_helpers.inferFieldMenuEditableFieldUse)((0, import_service_helpers.getFieldInterface)(field)) || "InputFieldModel" : (0, import_service_helpers.inferAssociationLeafDisplayFieldUse)((0, import_service_helpers.getFieldInterface)(field)) || "DisplayTextFieldModel";
14405
+ const title = (0, import_service_helpers.getFieldTitle)(field);
14406
+ const fieldInit = this.buildRelationTargetFieldInit(input.collection, input.fieldPath);
14407
+ return {
14408
+ uid: (0, import_utils.uid)(),
14409
+ use: input.wrapperUse,
14410
+ props: (0, import_service_utils.buildDefinedPayload)({
14411
+ label: title
14412
+ }),
14413
+ stepParams: {
14414
+ fieldSettings: {
14415
+ init: fieldInit
14416
+ }
14417
+ },
14418
+ subModels: {
14419
+ field: {
14420
+ uid: (0, import_utils.uid)(),
14421
+ use: fieldUse,
14422
+ props: this.normalizeFieldPropsForUse(
14423
+ fieldUse,
14424
+ (0, import_service_utils.getFieldBindingDefaultProps)(input.wrapperUse, fieldUse, field)
14425
+ ),
14426
+ stepParams: {
14427
+ fieldSettings: {
14428
+ init: fieldInit
14429
+ },
14430
+ fieldBinding: {
14431
+ use: fieldUse
14432
+ }
14433
+ }
14434
+ }
14435
+ }
14436
+ };
14437
+ }
14438
+ async replaceFieldSubModelArray(input) {
14439
+ var _a, _b;
14440
+ const parentNode = await this.repository.findModelById(input.parentUid, {
14441
+ transaction: input.transaction,
14442
+ includeAsyncNode: true
14443
+ });
14444
+ const keptChildren = [];
14445
+ for (const child of import_lodash.default.castArray(((_a = parentNode == null ? void 0 : parentNode.subModels) == null ? void 0 : _a[input.subKey]) || [])) {
14446
+ if (!(child == null ? void 0 : child.uid)) {
14447
+ continue;
14448
+ }
14449
+ if ((_b = input.keepUses) == null ? void 0 : _b.includes(child.use)) {
14450
+ keptChildren.push(child);
14451
+ continue;
14452
+ }
14453
+ await this.removeNodeTreeWithBindings(child.uid, input.transaction);
14454
+ }
14455
+ for (const child of keptChildren.reverse()) {
14456
+ await this.repository.attach(
14457
+ child.uid,
14458
+ {
14459
+ parentId: input.parentUid,
14460
+ subKey: input.subKey,
14461
+ subType: "array",
14462
+ position: "first"
14463
+ },
14464
+ { transaction: input.transaction }
14465
+ );
14466
+ }
14467
+ for (const child of input.children) {
14468
+ await this.repository.upsertModel(
14469
+ {
14470
+ parentId: input.parentUid,
14471
+ subKey: input.subKey,
14472
+ subType: "array",
14473
+ ...child
14474
+ },
14475
+ { transaction: input.transaction }
14476
+ );
14477
+ }
14478
+ }
14479
+ buildPopupSubTableActionsColumnNode(existing) {
14480
+ var _a, _b;
14481
+ const defaultActionColumn = import_lodash.default.cloneDeep(
14482
+ (_b = (_a = (0, import_builder.getStandaloneFieldDefaults)("PopupSubTableFieldModel").subModels) == null ? void 0 : _a.subTableColumns) == null ? void 0 : _b[0]
14483
+ );
14484
+ return {
14485
+ ...defaultActionColumn || {
14486
+ use: "PopupSubTableActionsColumnModel"
14487
+ },
14488
+ ...existing || {},
14489
+ uid: (existing == null ? void 0 : existing.uid) || (defaultActionColumn == null ? void 0 : defaultActionColumn.uid) || (0, import_utils.uid)()
14490
+ };
14491
+ }
14492
+ async ensureFieldGridSubModel(input) {
14493
+ var _a;
14494
+ const fieldNode = await this.repository.findModelById(input.fieldUid, {
14495
+ transaction: input.transaction,
14496
+ includeAsyncNode: true
14497
+ });
14498
+ const existingGrid = (_a = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _a.grid;
14499
+ if (existingGrid == null ? void 0 : existingGrid.uid) {
14500
+ return existingGrid.uid;
14501
+ }
14502
+ const gridUid = (0, import_utils.uid)();
14503
+ await this.repository.upsertModel(
14504
+ {
14505
+ uid: gridUid,
14506
+ parentId: input.fieldUid,
14507
+ subKey: "grid",
14508
+ subType: "object",
14509
+ use: input.gridUse
14510
+ },
14511
+ { transaction: input.transaction }
14512
+ );
14513
+ return gridUid;
14514
+ }
14515
+ async applyResolvedRelationFieldType(input) {
14516
+ var _a;
14517
+ if (input.titleField || !import_lodash.default.isUndefined(input.pageSize) || !import_lodash.default.isUndefined(input.showIndex)) {
14518
+ const fieldNode = await this.repository.findModelById(input.fieldUid, {
14519
+ transaction: input.transaction,
14520
+ includeAsyncNode: true
14521
+ });
14522
+ const props = (0, import_service_utils.buildDefinedPayload)({
14523
+ ...input.titleField && this.supportsFieldTitleFieldProp(input.fieldUse) ? { titleField: input.titleField } : {},
14524
+ pageSize: input.pageSize,
14525
+ showIndex: input.showIndex
14526
+ });
14527
+ if (Object.keys(props).length) {
14528
+ await this.repository.patch(
14529
+ {
14530
+ uid: input.fieldUid,
14531
+ props: {
14532
+ ...(fieldNode == null ? void 0 : fieldNode.props) || {},
14533
+ ...props
14534
+ }
14535
+ },
14536
+ { transaction: input.transaction }
14537
+ );
14538
+ }
14539
+ }
14540
+ const fields = input.fields;
14541
+ if ((0, import_field_type_resolver.usesNestedRelationFields)(input.fieldUse) && fields) {
14542
+ if (["SubTableFieldModel", "DisplaySubTableFieldModel"].includes(input.fieldUse)) {
14543
+ await this.replaceFieldSubModelArray({
14544
+ parentUid: input.fieldUid,
14545
+ subKey: "columns",
14546
+ children: fields.map(
14547
+ (fieldPath) => this.buildRelationTargetTableColumnNode({
14548
+ collection: input.targetCollection,
14549
+ fieldPath,
14550
+ columnUse: input.fieldUse === "SubTableFieldModel" ? "SubTableColumnModel" : "TableColumnModel"
14551
+ })
14552
+ ),
14553
+ transaction: input.transaction
14554
+ });
14555
+ } else if (input.fieldUse === "PopupSubTableFieldModel") {
14556
+ const fieldNode = await this.repository.findModelById(input.fieldUid, {
14557
+ transaction: input.transaction,
14558
+ includeAsyncNode: true
14559
+ });
14560
+ const existingActionsColumn = import_lodash.default.castArray(((_a = fieldNode == null ? void 0 : fieldNode.subModels) == null ? void 0 : _a.subTableColumns) || []).find(
14561
+ (item) => (item == null ? void 0 : item.use) === "PopupSubTableActionsColumnModel"
14562
+ );
14563
+ await this.replaceFieldSubModelArray({
14564
+ parentUid: input.fieldUid,
14565
+ subKey: "subTableColumns",
14566
+ children: [
14567
+ this.buildPopupSubTableActionsColumnNode(existingActionsColumn),
14568
+ ...fields.map(
14569
+ (fieldPath) => this.buildRelationTargetTableColumnNode({
14570
+ collection: input.targetCollection,
14571
+ fieldPath,
14572
+ columnUse: "TableColumnModel"
14573
+ })
14574
+ )
14575
+ ],
14576
+ transaction: input.transaction
14577
+ });
14578
+ } else {
14579
+ const gridUse = ["SubFormFieldModel", "SubFormListFieldModel"].includes(input.fieldUse) ? "FormGridModel" : "DetailsGridModel";
14580
+ const wrapperUse = ["SubFormFieldModel", "SubFormListFieldModel"].includes(input.fieldUse) ? "FormItemModel" : "DetailsItemModel";
14581
+ const gridUid = await this.ensureFieldGridSubModel({
14582
+ fieldUid: input.fieldUid,
14583
+ gridUse,
14584
+ transaction: input.transaction
14585
+ });
14586
+ await this.replaceFieldSubModelArray({
14587
+ parentUid: gridUid,
14588
+ subKey: "items",
14589
+ children: fields.map(
14590
+ (fieldPath) => this.buildRelationTargetGridItemNode({
14591
+ collection: input.targetCollection,
14592
+ fieldPath,
14593
+ wrapperUse
14594
+ })
14595
+ ),
14596
+ transaction: input.transaction
14597
+ });
14598
+ }
14599
+ }
14600
+ if (input.fieldUse === "RecordPickerFieldModel") {
14601
+ await this.applyRecordPickerFieldTypeSettings(input);
14602
+ }
14603
+ }
14604
+ async applyRecordPickerFieldTypeSettings(input) {
14605
+ var _a, _b, _c;
14606
+ const fieldNode = await this.repository.findModelById(input.fieldUid, {
14607
+ transaction: input.transaction,
14608
+ includeAsyncNode: true
14609
+ });
14610
+ const openView = (0, import_service_utils.buildDefinedPayload)({
14611
+ mode: input.openMode,
14612
+ size: input.popupSize,
14613
+ pageModelClass: "ChildPageModel",
14614
+ dataSourceKey: ((_a = input.targetCollection) == null ? void 0 : _a.dataSourceKey) || "main",
14615
+ collectionName: (0, import_service_helpers.getCollectionName)(input.targetCollection)
14616
+ });
14617
+ if (Object.keys(openView).length > 2) {
14618
+ await this.repository.patch(
14619
+ {
14620
+ uid: input.fieldUid,
14621
+ stepParams: import_lodash.default.merge({}, (fieldNode == null ? void 0 : fieldNode.stepParams) || {}, {
14622
+ popupSettings: {
14623
+ openView
14624
+ }
14625
+ })
14626
+ },
14627
+ { transaction: input.transaction }
14628
+ );
14629
+ }
14630
+ if (!input.selectorFields) {
14631
+ return;
14632
+ }
14633
+ let grid = await this.repository.findModelByParentId(input.fieldUid, {
14634
+ transaction: input.transaction,
14635
+ subKey: "grid-block",
14636
+ includeAsyncNode: true
14637
+ });
14638
+ if (!(grid == null ? void 0 : grid.uid)) {
14639
+ const gridUid = (0, import_utils.uid)();
14640
+ await this.repository.upsertModel(
14641
+ {
14642
+ uid: gridUid,
14643
+ parentId: input.fieldUid,
14644
+ subKey: "grid-block",
14645
+ subType: "object",
14646
+ use: "BlockGridModel"
14647
+ },
14648
+ { transaction: input.transaction }
14649
+ );
14650
+ grid = await this.repository.findModelById(gridUid, {
14651
+ transaction: input.transaction,
14652
+ includeAsyncNode: true
14653
+ });
14654
+ }
14655
+ if (!(grid == null ? void 0 : grid.uid)) {
14656
+ return;
14657
+ }
14658
+ const existingTable = import_lodash.default.castArray(((_b = grid == null ? void 0 : grid.subModels) == null ? void 0 : _b.items) || []).find(
14659
+ (item) => (item == null ? void 0 : item.use) === "TableBlockModel"
14660
+ );
14661
+ const tableUid = (existingTable == null ? void 0 : existingTable.uid) || (0, import_utils.uid)();
14662
+ if (!(existingTable == null ? void 0 : existingTable.uid)) {
14663
+ await this.repository.upsertModel(
14664
+ {
14665
+ uid: tableUid,
14666
+ parentId: grid.uid,
14667
+ subKey: "items",
14668
+ subType: "array",
14669
+ use: "TableBlockModel",
14670
+ stepParams: {
14671
+ resourceSettings: {
14672
+ init: {
14673
+ dataSourceKey: ((_c = input.targetCollection) == null ? void 0 : _c.dataSourceKey) || "main",
14674
+ collectionName: (0, import_service_helpers.getCollectionName)(input.targetCollection)
14675
+ }
14676
+ }
14677
+ }
14678
+ },
14679
+ { transaction: input.transaction }
14680
+ );
14681
+ }
14682
+ await this.replaceFieldSubModelArray({
14683
+ parentUid: tableUid,
14684
+ subKey: "columns",
14685
+ children: input.selectorFields.map(
14686
+ (fieldPath) => this.buildRelationTargetTableColumnNode({
14687
+ collection: input.targetCollection,
14688
+ fieldPath,
14689
+ columnUse: "TableColumnModel"
14690
+ })
14691
+ ),
14692
+ transaction: input.transaction
14693
+ });
14694
+ }
12692
14695
  buildExactFieldSettingsInitPayload(input) {
12693
14696
  return (0, import_service_utils.buildDefinedPayload)({
12694
14697
  dataSourceKey: input.dataSourceKey,
@@ -12796,7 +14799,7 @@ class FlowSurfacesService {
12796
14799
  const targetFieldUse = input.targetFieldUse;
12797
14800
  const normalizedTargetUse = String(targetFieldUse || "").trim();
12798
14801
  if (!normalizedTargetUse) {
12799
- (0, import_errors.throwBadRequest)("flowSurfaces configure fieldComponent cannot be empty");
14802
+ (0, import_errors.throwBadRequest)("flowSurfaces configure fieldType cannot be empty");
12800
14803
  }
12801
14804
  const normalizedWrapperUse = String(wrapperUse || "").trim();
12802
14805
  const containerUse = normalizedWrapperUse === "FormAssociationItemModel" ? "DetailsItemModel" : normalizedWrapperUse;
@@ -12811,7 +14814,7 @@ class FlowSurfacesService {
12811
14814
  });
12812
14815
  if (!(supportedFieldUses == null ? void 0 : supportedFieldUses.has(normalizedTargetUse))) {
12813
14816
  (0, import_errors.throwBadRequest)(
12814
- `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent '${normalizedTargetUse}'`
14817
+ `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType '${normalizedTargetUse}'`
12815
14818
  );
12816
14819
  }
12817
14820
  return normalizedTargetUse;
@@ -12822,7 +14825,7 @@ class FlowSurfacesService {
12822
14825
  });
12823
14826
  if (!(contract == null ? void 0 : contract.fieldUse)) {
12824
14827
  (0, import_errors.throwBadRequest)(
12825
- `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent '${normalizedTargetUse}'`
14828
+ `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType '${normalizedTargetUse}'`
12826
14829
  );
12827
14830
  }
12828
14831
  return contract.fieldUse;
@@ -12838,7 +14841,7 @@ class FlowSurfacesService {
12838
14841
  });
12839
14842
  if (!(supportedFieldUses == null ? void 0 : supportedFieldUses.has(normalizedTargetUse))) {
12840
14843
  (0, import_errors.throwBadRequest)(
12841
- `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent '${normalizedTargetUse}'`
14844
+ `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType '${normalizedTargetUse}'`
12842
14845
  );
12843
14846
  }
12844
14847
  return normalizedTargetUse;
@@ -12849,19 +14852,22 @@ class FlowSurfacesService {
12849
14852
  });
12850
14853
  if (!(contract == null ? void 0 : contract.fieldUse)) {
12851
14854
  (0, import_errors.throwBadRequest)(
12852
- `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent '${normalizedTargetUse}'`
14855
+ `flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType '${normalizedTargetUse}'`
12853
14856
  );
12854
14857
  }
12855
14858
  return contract.fieldUse;
12856
14859
  }
12857
- (0, import_errors.throwBadRequest)(`flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldComponent`);
14860
+ (0, import_errors.throwBadRequest)(`flowSurfaces configure field wrapper '${normalizedWrapperUse}' does not support fieldType`);
12858
14861
  }
12859
- async syncFieldComponentStepParams(wrapperNode, targetFieldUse, transaction) {
14862
+ async syncFieldTypeStepParams(wrapperNode, targetFieldUse, transaction) {
12860
14863
  const flowDomain = this.inferFieldComponentFlowDomain(wrapperNode == null ? void 0 : wrapperNode.use);
12861
14864
  if (!flowDomain || !(wrapperNode == null ? void 0 : wrapperNode.uid)) {
12862
14865
  return;
12863
14866
  }
12864
- const nextStepParams = import_lodash.default.merge({}, wrapperNode.stepParams || {}, {
14867
+ const latestWrapper = await this.repository.findModelById(wrapperNode.uid, {
14868
+ transaction
14869
+ });
14870
+ const nextStepParams = import_lodash.default.merge({}, (latestWrapper == null ? void 0 : latestWrapper.stepParams) || wrapperNode.stepParams || {}, {
12865
14871
  [flowDomain.flowKey]: {
12866
14872
  [flowDomain.stepKey]: {
12867
14873
  use: targetFieldUse
@@ -12877,7 +14883,7 @@ class FlowSurfacesService {
12877
14883
  );
12878
14884
  }
12879
14885
  async rebuildFieldSubModelOnServer(input) {
12880
- var _a, _b, _c, _d, _e;
14886
+ var _a, _b, _c, _d, _e, _f;
12881
14887
  const innerField = input.innerField;
12882
14888
  if (!(innerField == null ? void 0 : innerField.uid)) {
12883
14889
  (0, import_errors.throwConflict)(
@@ -12893,16 +14899,38 @@ class FlowSurfacesService {
12893
14899
  dataSourceKey: (_c = fieldSource.fieldSettingsInit) == null ? void 0 : _c.dataSourceKey,
12894
14900
  enabledPackages: input.enabledPackages
12895
14901
  });
14902
+ if (innerField.use === normalizedTargetUse) {
14903
+ await this.repository.patch(
14904
+ {
14905
+ uid: innerField.uid,
14906
+ stepParams: import_lodash.default.merge({}, innerField.stepParams || {}, {
14907
+ fieldBinding: {
14908
+ use: normalizedTargetUse
14909
+ },
14910
+ fieldSettings: {
14911
+ init: fieldSource.fieldSettingsInit
14912
+ }
14913
+ })
14914
+ },
14915
+ { transaction: input.transaction }
14916
+ );
14917
+ return normalizedTargetUse;
14918
+ }
12896
14919
  const defaultProps = (0, import_service_utils.getFieldBindingDefaultProps)((_d = input.wrapperNode) == null ? void 0 : _d.use, normalizedTargetUse, fieldSource.field);
14920
+ const fieldDefaults = (0, import_builder.getStandaloneFieldDefaults)(normalizedTargetUse);
12897
14921
  const shouldPreservePatternFormField = ((_e = input.wrapperNode) == null ? void 0 : _e.use) === "PatternFormItemModel";
14922
+ const preservedPopupPageSubModel = ((_f = input.innerField) == null ? void 0 : _f.subModels) && Object.prototype.hasOwnProperty.call(input.innerField.subModels, "page") ? {
14923
+ page: import_lodash.default.cloneDeep(input.innerField.subModels.page)
14924
+ } : {};
14925
+ const nextSubModels = {
14926
+ ...fieldDefaults.subModels ? import_lodash.default.cloneDeep(fieldDefaults.subModels) : {},
14927
+ ...preservedPopupPageSubModel
14928
+ };
12898
14929
  const nextFieldNode = {
12899
14930
  uid: innerField.uid,
12900
14931
  use: shouldPreservePatternFormField ? "PatternFormFieldModel" : normalizedTargetUse,
12901
14932
  props: import_lodash.default.pickBy(
12902
- {
12903
- ...innerField.props || {},
12904
- ...defaultProps
12905
- },
14933
+ this.normalizeFieldPropsForUse(normalizedTargetUse, { ...innerField.props || {}, ...defaultProps }),
12906
14934
  (value) => !import_lodash.default.isUndefined(value)
12907
14935
  ),
12908
14936
  decoratorProps: import_lodash.default.cloneDeep(innerField.decoratorProps || {}),
@@ -12914,7 +14942,8 @@ class FlowSurfacesService {
12914
14942
  fieldSettings: {
12915
14943
  init: fieldSource.fieldSettingsInit
12916
14944
  }
12917
- })
14945
+ }),
14946
+ subModels: nextSubModels
12918
14947
  };
12919
14948
  await this.repository.patch(nextFieldNode, { transaction: input.transaction });
12920
14949
  return normalizedTargetUse;
@@ -12955,7 +14984,7 @@ class FlowSurfacesService {
12955
14984
  associationField
12956
14985
  };
12957
14986
  }
12958
- async loadResolvedNode(resolved, transaction) {
14987
+ async loadResolvedNode(resolved, transaction, options = {}) {
12959
14988
  var _a;
12960
14989
  let node;
12961
14990
  if ((resolved == null ? void 0 : resolved.kind) === "page" && (resolved == null ? void 0 : resolved.pageRoute)) {
@@ -12967,7 +14996,13 @@ class FlowSurfacesService {
12967
14996
  } else {
12968
14997
  node = await this.repository.findModelById(resolved.uid, { transaction, includeAsyncNode: true });
12969
14998
  }
12970
- return this.ensureCalendarBlockPopupHostsInTree(node, transaction);
14999
+ if (options.persistCalendarPopupHosts === false) {
15000
+ return this.projectKanbanBlockPopupHostsInTree(this.projectCalendarBlockPopupHostsInTree(node));
15001
+ }
15002
+ return this.ensureKanbanBlockPopupHostsInTree(
15003
+ await this.ensureCalendarBlockPopupHostsInTree(node, transaction),
15004
+ transaction
15005
+ );
12971
15006
  }
12972
15007
  normalizePopupTreeShape(node) {
12973
15008
  if (!node || typeof node !== "object") {