@nocobase/plugin-flow-engine 2.1.0-alpha.20 → 2.1.0-alpha.21

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 (50) hide show
  1. package/dist/externalVersion.js +11 -10
  2. package/dist/node_modules/ses/dist/ses.cjs +1 -1
  3. package/dist/node_modules/ses/package.json +1 -1
  4. package/dist/node_modules/zod/index.cjs +1 -1
  5. package/dist/node_modules/zod/package.json +1 -1
  6. package/dist/server/flow-surfaces/action-scope.d.ts +1 -0
  7. package/dist/server/flow-surfaces/action-scope.js +4 -0
  8. package/dist/server/flow-surfaces/apply/compiler.js +1 -1
  9. package/dist/server/flow-surfaces/approval/builder.js +8 -8
  10. package/dist/server/flow-surfaces/blueprint/compile-blocks.js +192 -29
  11. package/dist/server/flow-surfaces/blueprint/defaults.d.ts +26 -0
  12. package/dist/server/flow-surfaces/blueprint/defaults.js +133 -0
  13. package/dist/server/flow-surfaces/blueprint/index.d.ts +1 -1
  14. package/dist/server/flow-surfaces/blueprint/normalize-document.js +121 -1
  15. package/dist/server/flow-surfaces/blueprint/public-types.d.ts +32 -0
  16. package/dist/server/flow-surfaces/builder.d.ts +2 -2
  17. package/dist/server/flow-surfaces/builder.js +148 -50
  18. package/dist/server/flow-surfaces/catalog.js +276 -34
  19. package/dist/server/flow-surfaces/compose-compiler.d.ts +2 -0
  20. package/dist/server/flow-surfaces/compose-compiler.js +5 -1
  21. package/dist/server/flow-surfaces/configure-options.js +88 -12
  22. package/dist/server/flow-surfaces/contract-guard.js +60 -69
  23. package/dist/server/flow-surfaces/default-action-popup.d.ts +11 -1
  24. package/dist/server/flow-surfaces/default-action-popup.js +72 -12
  25. package/dist/server/flow-surfaces/default-block-actions.js +8 -1
  26. package/dist/server/flow-surfaces/filter-group.d.ts +15 -0
  27. package/dist/server/flow-surfaces/filter-group.js +94 -0
  28. package/dist/server/flow-surfaces/index.js +70 -2
  29. package/dist/server/flow-surfaces/node-use-sets.js +6 -1
  30. package/dist/server/flow-surfaces/placement.js +3 -0
  31. package/dist/server/flow-surfaces/public-data-surface-default-filter.d.ts +20 -0
  32. package/dist/server/flow-surfaces/public-data-surface-default-filter.js +111 -0
  33. package/dist/server/flow-surfaces/reaction/registry.d.ts +7 -0
  34. package/dist/server/flow-surfaces/reaction/registry.js +7 -0
  35. package/dist/server/flow-surfaces/service-utils.d.ts +7 -0
  36. package/dist/server/flow-surfaces/service-utils.js +58 -9
  37. package/dist/server/flow-surfaces/service.d.ts +73 -3
  38. package/dist/server/flow-surfaces/service.js +1794 -162
  39. package/dist/server/flow-surfaces/support-matrix.d.ts +5 -2
  40. package/dist/server/flow-surfaces/support-matrix.js +16 -3
  41. package/dist/server/flow-surfaces/surface-context.js +2 -1
  42. package/dist/server/flow-surfaces/template-display.d.ts +20 -0
  43. package/dist/server/flow-surfaces/template-display.js +289 -0
  44. package/dist/server/flow-surfaces/types.d.ts +1 -0
  45. package/dist/swagger/flow-surfaces.d.ts +160 -0
  46. package/dist/swagger/flow-surfaces.examples.d.ts +117 -11
  47. package/dist/swagger/flow-surfaces.examples.js +152 -1
  48. package/dist/swagger/flow-surfaces.js +141 -21
  49. package/dist/swagger/index.d.ts +160 -0
  50. package/package.json +2 -2
@@ -50,6 +50,7 @@ var import_compiler = require("./apply/compiler");
50
50
  var import_layout = require("./apply/layout");
51
51
  var import_contract_guard = require("./contract-guard");
52
52
  var import_errors = require("./errors");
53
+ var import_filter_group = require("./filter-group");
53
54
  var import_executor = require("./executor");
54
55
  var import_reference_guards = require("./reference-guards");
55
56
  var import_key_registry = require("./planning/key-registry");
@@ -57,6 +58,7 @@ var import_blueprint = require("./blueprint");
57
58
  var import_compile_blocks = require("./blueprint/compile-blocks");
58
59
  var import_private_utils = require("./blueprint/private-utils");
59
60
  var import_default_block_actions = require("./default-block-actions");
61
+ var import_public_data_surface_default_filter = require("./public-data-surface-default-filter");
60
62
  var import_runtime = require("./planning/runtime");
61
63
  var import_created_keys = require("./planning/created-keys");
62
64
  var import_key_persistence = require("./planning/key-persistence");
@@ -76,6 +78,7 @@ var import_context = require("./context");
76
78
  var import_configure_options = require("./configure-options");
77
79
  var import_service_helpers = require("./service-helpers");
78
80
  var import_errors2 = require("./reaction/errors");
81
+ var import_template_display = require("./template-display");
79
82
  var import_approval = require("./approval");
80
83
  var import_field_value = require("./reaction/field-value");
81
84
  var import_fingerprint = require("./reaction/fingerprint");
@@ -84,10 +87,13 @@ var import_meta = require("./reaction/meta");
84
87
  var import_resolver = require("./reaction/resolver");
85
88
  var import_association_title_field = require("./association-title-field");
86
89
  var import_default_action_popup = require("./default-action-popup");
90
+ var import_defaults = require("./blueprint/defaults");
87
91
  var import_service_utils = require("./service-utils");
88
92
  var import_template_compatibility = require("./template-compatibility");
89
93
  var import_template_service_utils = require("./template-service-utils");
90
94
  const FORM_BLOCK_USES = /* @__PURE__ */ new Set(["FormBlockModel", "CreateFormModel", "EditFormModel", ...import_approval.APPROVAL_FORM_BLOCK_USES]);
95
+ const AUTO_SUBMIT_FORM_BLOCK_USES = /* @__PURE__ */ new Set(["CreateFormModel", "EditFormModel"]);
96
+ const FLOW_SURFACE_DEFAULT_ACTION_SETTINGS_KEYS = /* @__PURE__ */ new Set(["filter"]);
91
97
  const DETAILS_BLOCK_USES = /* @__PURE__ */ new Set(["DetailsBlockModel", ...import_approval.APPROVAL_DETAILS_BLOCK_USES]);
92
98
  const SIMPLE_FORM_BLOCK_USES = /* @__PURE__ */ new Set([
93
99
  "FormBlockModel",
@@ -96,8 +102,37 @@ const SIMPLE_FORM_BLOCK_USES = /* @__PURE__ */ new Set([
96
102
  ...import_approval.APPROVAL_FORM_BLOCK_USES
97
103
  ]);
98
104
  const COMPOSE_FIELD_GRID_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "editForm", "details", "filterForm"]);
105
+ const COMPOSE_FIELD_GROUP_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "editForm", "details"]);
99
106
  const LIST_BLOCK_USES = /* @__PURE__ */ new Set(["ListBlockModel"]);
100
107
  const GRID_CARD_BLOCK_USES = /* @__PURE__ */ new Set(["GridCardBlockModel"]);
108
+ const DEFAULT_CALENDAR_TITLE_FIELD_INTERFACES = ["input", "select", "phone", "email", "radioGroup"];
109
+ const DEFAULT_CALENDAR_COLOR_FIELD_INTERFACES = ["select", "radioGroup"];
110
+ const DEFAULT_CALENDAR_DATE_TIME_FIELD_TYPES = [
111
+ "date",
112
+ "datetime",
113
+ "dateOnly",
114
+ "datetimeNoTz",
115
+ "unixTimestamp",
116
+ "createdAt",
117
+ "updatedAt"
118
+ ];
119
+ const CALENDAR_POPUP_ACTION_KEYS = ["quickCreateAction", "eventViewAction"];
120
+ const CANONICAL_BLOCK_HEADER_USES = /* @__PURE__ */ new Set([
121
+ "TableBlockModel",
122
+ "CalendarBlockModel",
123
+ "FormBlockModel",
124
+ "CreateFormModel",
125
+ "EditFormModel",
126
+ "DetailsBlockModel",
127
+ "ListBlockModel",
128
+ "GridCardBlockModel",
129
+ "MarkdownBlockModel",
130
+ "IframeBlockModel",
131
+ "ChartBlockModel",
132
+ "ActionPanelBlockModel",
133
+ "MapBlockModel",
134
+ "CommentsBlockModel"
135
+ ]);
101
136
  const LIST_LIKE_COMPOSE_BLOCK_TYPES = /* @__PURE__ */ new Set(["list", "gridCard"]);
102
137
  const GRID_SETTINGS_FLOW_KEY = "gridSettings";
103
138
  const GRID_SETTINGS_LAYOUT_STEP_KEY = "grid";
@@ -108,6 +143,7 @@ const OPEN_VIEW_MODE_ALIASES = {
108
143
  const OPEN_VIEW_SUPPORTED_MODES = /* @__PURE__ */ new Set(["drawer", "dialog", "embed"]);
109
144
  const FILTER_TARGET_BLOCK_USES = /* @__PURE__ */ new Set([
110
145
  "TableBlockModel",
146
+ "CalendarBlockModel",
111
147
  "DetailsBlockModel",
112
148
  "ListBlockModel",
113
149
  "GridCardBlockModel",
@@ -183,6 +219,8 @@ const POPUP_ACTION_USES = /* @__PURE__ */ new Set([
183
219
  "ViewActionModel",
184
220
  "EditActionModel",
185
221
  "PopupCollectionActionModel",
222
+ "CalendarQuickCreateActionModel",
223
+ "CalendarEventViewActionModel",
186
224
  "DuplicateActionModel",
187
225
  "AddChildActionModel",
188
226
  "MailSendActionModel"
@@ -191,6 +229,7 @@ const POPUP_HOST_DEFAULT_RECORD_CONTEXT_ACTION_USES = /* @__PURE__ */ new Set([
191
229
  "ViewActionModel",
192
230
  "EditActionModel",
193
231
  "PopupCollectionActionModel",
232
+ "CalendarEventViewActionModel",
194
233
  "AddChildActionModel",
195
234
  "DuplicateActionModel"
196
235
  ]);
@@ -237,6 +276,7 @@ const POPUP_COLLECTION_BLOCK_SCENES = {
237
276
  ApprovalDetailsModel: ["one"],
238
277
  CommentsBlockModel: ["one", "many"],
239
278
  TableBlockModel: ["many"],
279
+ CalendarBlockModel: ["many"],
240
280
  ListBlockModel: ["many"],
241
281
  GridCardBlockModel: ["many"],
242
282
  MapBlockModel: ["many"],
@@ -309,6 +349,13 @@ const FILTER_FORM_BLOCK_LAYOUT_STEP_PARAM_MIRRORS = [
309
349
  { domain: "props", key: "labelWidth", stepParamsPath: ["formFilterBlockModelSettings", "layout", "labelWidth"] },
310
350
  { domain: "props", key: "labelWrap", stepParamsPath: ["formFilterBlockModelSettings", "layout", "labelWrap"] }
311
351
  ];
352
+ const DIVIDER_ITEM_STEP_PARAM_MIRRORS = [
353
+ { domain: "props", key: "label", stepParamsPath: ["markdownItemSetting", "title", "label"] },
354
+ { domain: "props", key: "orientation", stepParamsPath: ["markdownItemSetting", "title", "orientation"] },
355
+ { domain: "props", key: "dashed", stepParamsPath: ["markdownItemSetting", "title", "dashed"] },
356
+ { domain: "props", key: "color", stepParamsPath: ["markdownItemSetting", "title", "color"] },
357
+ { domain: "props", key: "borderColor", stepParamsPath: ["markdownItemSetting", "title", "borderColor"] }
358
+ ];
312
359
  const UPDATE_SETTINGS_STEP_PARAM_MIRRORS_BY_USE = {
313
360
  TableActionsColumnModel: TABLE_COLUMN_STEP_PARAM_MIRRORS,
314
361
  JSColumnModel: TABLE_COLUMN_STEP_PARAM_MIRRORS,
@@ -330,9 +377,15 @@ const UPDATE_SETTINGS_STEP_PARAM_MIRRORS_BY_USE = {
330
377
  ApprovalDetailsModel: DETAILS_BLOCK_LAYOUT_STEP_PARAM_MIRRORS,
331
378
  ApplyTaskCardDetailsModel: DETAILS_BLOCK_LAYOUT_STEP_PARAM_MIRRORS,
332
379
  ApprovalTaskCardDetailsModel: DETAILS_BLOCK_LAYOUT_STEP_PARAM_MIRRORS,
333
- FilterFormBlockModel: FILTER_FORM_BLOCK_LAYOUT_STEP_PARAM_MIRRORS
380
+ FilterFormBlockModel: FILTER_FORM_BLOCK_LAYOUT_STEP_PARAM_MIRRORS,
381
+ DividerItemModel: DIVIDER_ITEM_STEP_PARAM_MIRRORS
334
382
  };
335
383
  const FLOW_SURFACE_MENU_BINDABLE_OPTION_KEY = "flowSurfaceMenuBindable";
384
+ function normalizeCalendarFieldCapabilityValues(source, defaults) {
385
+ const rawValues = Array.isArray(source) ? source : source instanceof Set ? Array.from(source) : typeof source === "string" ? [source] : source && typeof source === "object" ? Object.keys(source) : [];
386
+ const values = rawValues.map((item) => String(item || "").trim()).filter(Boolean);
387
+ return values.length ? Array.from(new Set(values)) : [...defaults];
388
+ }
336
389
  class FlowSurfacesService {
337
390
  constructor(plugin) {
338
391
  this.plugin = plugin;
@@ -1066,6 +1119,16 @@ class FlowSurfacesService {
1066
1119
  recordActionContainerUse: (parentNode == null ? void 0 : parentNode.use) && POPUP_RECORD_ACTION_CONTAINER_USES.has(parentNode.use) ? parentNode.use : null
1067
1120
  };
1068
1121
  }
1122
+ popupHostUsesDefaultRecordContext(hostNode, hostContext) {
1123
+ const hostUse = String((hostNode == null ? void 0 : hostNode.use) || "").trim();
1124
+ if (!POPUP_HOST_DEFAULT_RECORD_CONTEXT_ACTION_USES.has(hostUse)) {
1125
+ return false;
1126
+ }
1127
+ if (hostUse === "CalendarEventViewActionModel") {
1128
+ return true;
1129
+ }
1130
+ return !!(hostContext == null ? void 0 : hostContext.recordActionContainerUse);
1131
+ }
1069
1132
  buildPopupBlockResourceBindings(blockUse, popupProfile, options = {}) {
1070
1133
  if (!this.isCollectionBlockUse(blockUse) || options.forCatalog && !this.isPopupCollectionBlockVisibleForScene(blockUse, popupProfile)) {
1071
1134
  return [];
@@ -1170,7 +1233,7 @@ class FlowSurfacesService {
1170
1233
  const collectionName = String((openView == null ? void 0 : openView.collectionName) || "").trim() || String(((_c = hostContext.associationContext) == null ? void 0 : _c.collectionName) || "").trim() || String(ownerResourceInit.collectionName || "").trim() || void 0;
1171
1234
  let filterByTk = openView == null ? void 0 : openView.filterByTk;
1172
1235
  let hasCurrentRecord = (0, import_service_helpers.hasConfiguredFlowContextValue)(filterByTk);
1173
- if (!hasCurrentRecord && POPUP_HOST_DEFAULT_RECORD_CONTEXT_ACTION_USES.has((hostNode == null ? void 0 : hostNode.use) || "") && hostContext.recordActionContainerUse) {
1236
+ if (!hasCurrentRecord && this.popupHostUsesDefaultRecordContext(hostNode, hostContext)) {
1174
1237
  filterByTk = "{{ctx.view.inputArgs.filterByTk}}";
1175
1238
  hasCurrentRecord = true;
1176
1239
  }
@@ -2694,7 +2757,7 @@ class FlowSurfacesService {
2694
2757
  const data = rows.map((row) => (0, import_service_helpers.toTemplatePlainRow)(row)).filter(Boolean);
2695
2758
  const templateUids = data.map((row) => String((row == null ? void 0 : row.uid) || "").trim()).filter(Boolean);
2696
2759
  if (!templateUids.length) {
2697
- return data;
2760
+ return (0, import_template_display.resolveFlowTemplateDisplayRows)(this.db, data, options);
2698
2761
  }
2699
2762
  const UsageModel = this.getFlowTemplateUsageModel(actionName);
2700
2763
  const usageRows = await UsageModel.findAll({
@@ -2710,10 +2773,14 @@ class FlowSurfacesService {
2710
2773
  for (const row of usageRows) {
2711
2774
  usageMap.set(String(row.templateUid), Number(row.count) || 0);
2712
2775
  }
2713
- return data.map((row) => ({
2714
- ...row,
2715
- usageCount: usageMap.get(String(row.uid || "")) || 0
2716
- }));
2776
+ return (0, import_template_display.resolveFlowTemplateDisplayRows)(
2777
+ this.db,
2778
+ data.map((row) => ({
2779
+ ...row,
2780
+ usageCount: usageMap.get(String(row.uid || "")) || 0
2781
+ })),
2782
+ options
2783
+ );
2717
2784
  }
2718
2785
  async listTemplates(values = {}, options = {}) {
2719
2786
  const repo = this.getFlowTemplateRepository("listTemplates");
@@ -2789,7 +2856,7 @@ class FlowSurfacesService {
2789
2856
  "FLOW_SURFACE_TEMPLATE_POPUP_SOURCE_UNSUPPORTED"
2790
2857
  );
2791
2858
  }
2792
- if (popupTemplateUid) {
2859
+ if (popupTemplateUid && !this.isEditableDefaultActionPopupTemplateReference(node, openView)) {
2793
2860
  (0, import_errors.throwBadRequest)(
2794
2861
  `flowSurfaces ${actionName} target '${node.uid}' already uses a popup template; convert it to copy first`,
2795
2862
  "FLOW_SURFACE_TEMPLATE_SOURCE_ALREADY_TEMPLATED"
@@ -2865,6 +2932,49 @@ class FlowSurfacesService {
2865
2932
  buildPopupTemplateReferenceOpenView(template, templateTargetUid) {
2866
2933
  return this.buildPopupTemplateOpenView(template, "reference", templateTargetUid);
2867
2934
  }
2935
+ async hydrateDetachedPopupTemplateSourceContext(templateTargetUid, inferred, transaction) {
2936
+ if (inferred.templateType !== "popup") {
2937
+ return;
2938
+ }
2939
+ const normalizedTemplateTargetUid = String(templateTargetUid || "").trim();
2940
+ if (!normalizedTemplateTargetUid) {
2941
+ return;
2942
+ }
2943
+ const detachedTarget = await this.repository.findModelById(normalizedTemplateTargetUid, {
2944
+ transaction,
2945
+ includeAsyncNode: true
2946
+ });
2947
+ if (!(detachedTarget == null ? void 0 : detachedTarget.uid)) {
2948
+ return;
2949
+ }
2950
+ const resolvedOpenViewStep = (0, import_template_service_utils.findFlowTemplateOpenViewStep)(detachedTarget) || inferred.openViewStep;
2951
+ if (!resolvedOpenViewStep) {
2952
+ return;
2953
+ }
2954
+ const nextStepParams = import_lodash.default.cloneDeep(detachedTarget.stepParams || {});
2955
+ const currentGroup = import_lodash.default.isPlainObject(nextStepParams[resolvedOpenViewStep.flowKey]) ? import_lodash.default.cloneDeep(nextStepParams[resolvedOpenViewStep.flowKey]) : {};
2956
+ const currentOpenView = import_lodash.default.isPlainObject(currentGroup[resolvedOpenViewStep.stepKey]) ? import_lodash.default.omit((0, import_template_service_utils.stripTemplateInternalOpenViewFields)(currentGroup[resolvedOpenViewStep.stepKey]) || {}, ["uid"]) : {};
2957
+ const nextOpenView = (0, import_service_utils.buildDefinedPayload)({
2958
+ ...currentOpenView,
2959
+ dataSourceKey: inferred.dataSourceKey || currentOpenView.dataSourceKey,
2960
+ collectionName: inferred.collectionName || currentOpenView.collectionName,
2961
+ associationName: inferred.associationName || currentOpenView.associationName,
2962
+ filterByTk: inferred.filterByTk || currentOpenView.filterByTk,
2963
+ sourceId: inferred.sourceId || currentOpenView.sourceId
2964
+ });
2965
+ if (import_lodash.default.isEqual(nextOpenView, currentOpenView)) {
2966
+ return;
2967
+ }
2968
+ currentGroup[resolvedOpenViewStep.stepKey] = nextOpenView;
2969
+ nextStepParams[resolvedOpenViewStep.flowKey] = currentGroup;
2970
+ await this.repository.patch(
2971
+ {
2972
+ uid: detachedTarget.uid,
2973
+ stepParams: nextStepParams
2974
+ },
2975
+ { transaction }
2976
+ );
2977
+ }
2868
2978
  async clearFlowTemplateUsagesByModelUids(modelUids, transaction) {
2869
2979
  const usageRepo = this.getFlowTemplateUsageRepositorySafe();
2870
2980
  if (!usageRepo) {
@@ -3135,6 +3245,7 @@ class FlowSurfacesService {
3135
3245
  );
3136
3246
  }
3137
3247
  if (inferred.templateType === "popup") {
3248
+ await this.hydrateDetachedPopupTemplateSourceContext(templateTargetUid, inferred, options.transaction);
3138
3249
  await this.ensurePopupSurface(templateTargetUid, options.transaction);
3139
3250
  }
3140
3251
  const templateUid = String((values == null ? void 0 : values.uid) || (0, import_utils.uid)()).trim() || (0, import_utils.uid)();
@@ -3614,6 +3725,12 @@ class FlowSurfacesService {
3614
3725
  }),
3615
3726
  applyActionPopup: async (actionName, actionUid, popup) => this.applyInlineActionPopup(actionName, actionUid, popup, {
3616
3727
  ...options,
3728
+ enabledPackages,
3729
+ ...actionName === "compose recordAction" ? {
3730
+ popupActionContext: {
3731
+ hasCurrentRecord: true
3732
+ }
3733
+ } : {},
3617
3734
  popupTemplateAliasSession
3618
3735
  }),
3619
3736
  collectActionKeys: async (actionUid) => this.collectComposeActionKeys(actionUid, options.transaction),
@@ -3662,6 +3779,9 @@ class FlowSurfacesService {
3662
3779
  if ((current == null ? void 0 : current.use) === "TableBlockModel") {
3663
3780
  return this.configureTableBlock(target, values.changes, options);
3664
3781
  }
3782
+ if ((current == null ? void 0 : current.use) === "CalendarBlockModel") {
3783
+ return this.configureCalendarBlock(target, current, values.changes, options);
3784
+ }
3665
3785
  if (SIMPLE_FORM_BLOCK_USES.has((current == null ? void 0 : current.use) || "")) {
3666
3786
  return this.configureFormBlock(target, current.use, values.changes, options);
3667
3787
  }
@@ -3692,6 +3812,12 @@ class FlowSurfacesService {
3692
3812
  if ((current == null ? void 0 : current.use) === "ActionPanelBlockModel") {
3693
3813
  return this.configureActionPanelBlock(target, values.changes, options);
3694
3814
  }
3815
+ if ((current == null ? void 0 : current.use) === "MapBlockModel") {
3816
+ return this.configureMapBlock(target, values.changes, options);
3817
+ }
3818
+ if ((current == null ? void 0 : current.use) === "CommentsBlockModel") {
3819
+ return this.configureCommentsBlock(target, values.changes, options);
3820
+ }
3695
3821
  if ((current == null ? void 0 : current.use) === "TableActionsColumnModel") {
3696
3822
  return this.configureActionColumn(target, values.changes, options);
3697
3823
  }
@@ -3699,7 +3825,13 @@ class FlowSurfacesService {
3699
3825
  return this.configureFieldWrapper(target, current, values.changes, options);
3700
3826
  }
3701
3827
  if (import_node_use_sets.STANDALONE_FIELD_NODE_USES.has((current == null ? void 0 : current.use) || "")) {
3702
- return (current == null ? void 0 : current.use) === "JSColumnModel" ? this.configureJSColumn(target, values.changes, options) : this.configureJSItem(target, values.changes, options);
3828
+ if ((current == null ? void 0 : current.use) === "JSColumnModel") {
3829
+ return this.configureJSColumn(target, values.changes, options);
3830
+ }
3831
+ if ((current == null ? void 0 : current.use) === "DividerItemModel") {
3832
+ return this.configureDividerItem(target, values.changes, options);
3833
+ }
3834
+ return this.configureJSItem(target, values.changes, options);
3703
3835
  }
3704
3836
  if ((0, import_service_utils.isFieldNodeUse)(current == null ? void 0 : current.use)) {
3705
3837
  return this.configureFieldNode(target, values.changes, options);
@@ -4580,12 +4712,83 @@ class FlowSurfacesService {
4580
4712
  ...result
4581
4713
  };
4582
4714
  }
4715
+ normalizeDefaultActionSettings(actionName, value) {
4716
+ if (import_lodash.default.isUndefined(value)) {
4717
+ return void 0;
4718
+ }
4719
+ if (!import_lodash.default.isPlainObject(value)) {
4720
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} defaultActionSettings must be an object`);
4721
+ }
4722
+ const result = {};
4723
+ for (const [rawActionType, rawSettings] of Object.entries(value)) {
4724
+ const actionType = String(rawActionType || "").trim();
4725
+ if (!FLOW_SURFACE_DEFAULT_ACTION_SETTINGS_KEYS.has(actionType)) {
4726
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} defaultActionSettings does not support '${rawActionType}'`);
4727
+ }
4728
+ result[actionType] = import_lodash.default.cloneDeep(rawSettings);
4729
+ }
4730
+ return result;
4731
+ }
4732
+ normalizeDefaultFilterActionSettings(actionName, settings) {
4733
+ if (!import_lodash.default.isPlainObject(settings)) {
4734
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} defaultActionSettings.filter must be an object`);
4735
+ }
4736
+ const normalizedSettings = import_lodash.default.cloneDeep(settings);
4737
+ if ((0, import_service_utils.hasOwnDefined)(normalizedSettings, "filterableFieldNames")) {
4738
+ if (!Array.isArray(normalizedSettings.filterableFieldNames)) {
4739
+ (0, import_errors.throwBadRequest)(
4740
+ `flowSurfaces ${actionName} defaultActionSettings.filter.filterableFieldNames must be an array`
4741
+ );
4742
+ }
4743
+ normalizedSettings.filterableFieldNames.forEach((fieldName, index) => {
4744
+ if (typeof fieldName !== "string") {
4745
+ (0, import_errors.throwBadRequest)(
4746
+ `flowSurfaces ${actionName} defaultActionSettings.filter.filterableFieldNames[${index}] expected string`
4747
+ );
4748
+ }
4749
+ });
4750
+ }
4751
+ if ((0, import_service_utils.hasOwnDefined)(normalizedSettings, "defaultFilter")) {
4752
+ normalizedSettings.defaultFilter = (0, import_filter_group.normalizeFlowSurfaceFilterGroupValue)(
4753
+ normalizedSettings.defaultFilter,
4754
+ `flowSurfaces ${actionName} defaultActionSettings.filter.defaultFilter expects FilterGroup like ${import_filter_group.FLOW_SURFACE_FILTER_GROUP_EXAMPLE}`
4755
+ );
4756
+ }
4757
+ return normalizedSettings;
4758
+ }
4759
+ backfillBlockDefaultFilterIntoDefaultActionSettings(defaultActionSettings, blockDefaultFilter) {
4760
+ if (import_lodash.default.isUndefined(blockDefaultFilter)) {
4761
+ return defaultActionSettings;
4762
+ }
4763
+ const nextFilterSettings = (0, import_public_data_surface_default_filter.backfillFlowSurfaceDefaultFilterSetting)(
4764
+ defaultActionSettings == null ? void 0 : defaultActionSettings.filter,
4765
+ blockDefaultFilter
4766
+ );
4767
+ if (nextFilterSettings === (defaultActionSettings == null ? void 0 : defaultActionSettings.filter)) {
4768
+ return defaultActionSettings;
4769
+ }
4770
+ return {
4771
+ ...defaultActionSettings || {},
4772
+ filter: nextFilterSettings
4773
+ };
4774
+ }
4583
4775
  async addBlock(values, options = {}) {
4584
4776
  var _a, _b, _c, _d, _e;
4585
- const templateRef = !import_lodash.default.isUndefined(values == null ? void 0 : values.template) ? this.normalizeFlowTemplateReference("addBlock", values.template, {
4777
+ const templateRef = import_lodash.default.isUndefined(values == null ? void 0 : values.template) ? void 0 : this.normalizeFlowTemplateReference("addBlock", values.template, {
4586
4778
  allowUsage: true,
4587
4779
  expectedType: "block"
4588
- }) : null;
4780
+ });
4781
+ const blockDefaultFilter = (0, import_public_data_surface_default_filter.normalizeFlowSurfacePublicBlockDefaultFilter)("addBlock", values.defaultFilter, {
4782
+ blockType: String((values == null ? void 0 : values.type) || "").trim() || void 0,
4783
+ template: templateRef
4784
+ });
4785
+ const defaultActionSettings = this.backfillBlockDefaultFilterIntoDefaultActionSettings(
4786
+ this.normalizeDefaultActionSettings("addBlock", values.defaultActionSettings),
4787
+ blockDefaultFilter
4788
+ );
4789
+ if (templateRef && !import_lodash.default.isUndefined(values.defaultActionSettings)) {
4790
+ (0, import_errors.throwBadRequest)(`flowSurfaces addBlock template import does not allow defaultActionSettings`);
4791
+ }
4589
4792
  if (templateRef) {
4590
4793
  const result2 = await this.addBlockFromTemplate(values, templateRef, options);
4591
4794
  await this.persistCreatedKeysForAction("addBlock", values, result2, options.transaction);
@@ -4647,6 +4850,15 @@ class FlowSurfacesService {
4647
4850
  resourceInit: resolvedResourceInit,
4648
4851
  resourceField: rawResourceInit ? "resourceInit" : (semanticResource == null ? void 0 : semanticResource.kind) === "raw" ? "resource" : void 0
4649
4852
  });
4853
+ const effectiveResourceInit = catalogItem.use === "CalendarBlockModel" && resolvedResourceInit.collectionName && !resolvedResourceInit.dataSourceKey ? {
4854
+ ...resolvedResourceInit,
4855
+ dataSourceKey: "main"
4856
+ } : resolvedResourceInit;
4857
+ const blockProps = catalogItem.use === "CalendarBlockModel" ? this.buildCalendarInitialBlockProps({
4858
+ actionName: "addBlock",
4859
+ resourceInit: effectiveResourceInit,
4860
+ props: values.props
4861
+ }) : values.props;
4650
4862
  const initialGrid = options.deferAutoLayout ? null : await this.repository.findModelById(parentUid, {
4651
4863
  transaction: options.transaction,
4652
4864
  includeAsyncNode: true
@@ -4654,8 +4866,8 @@ class FlowSurfacesService {
4654
4866
  const tree = (0, import_builder.buildBlockTree)({
4655
4867
  use: catalogItem.use,
4656
4868
  containerUse: parentNode == null ? void 0 : parentNode.use,
4657
- resourceInit: resolvedResourceInit,
4658
- props: values.props,
4869
+ resourceInit: effectiveResourceInit,
4870
+ props: blockProps,
4659
4871
  decoratorProps: values.decoratorProps,
4660
4872
  stepParams: values.stepParams
4661
4873
  });
@@ -4698,7 +4910,8 @@ class FlowSurfacesService {
4698
4910
  await this.applyDefaultActionsForCreatedBlock(
4699
4911
  {
4700
4912
  blockUid: created,
4701
- blockType: String(catalogItem.key || values.type || "").trim()
4913
+ blockType: String(catalogItem.key || values.type || "").trim(),
4914
+ defaultActionSettings
4702
4915
  },
4703
4916
  {
4704
4917
  ...options,
@@ -4926,7 +5139,10 @@ class FlowSurfacesService {
4926
5139
  if (values.__autoPopupForRelationField === true && !inlinePopup && this.isPopupFieldHostUse(boundFieldCapability.fieldUse) && ((0, import_service_helpers.isAssociationField)(resolvedField.field) || !!normalizedFieldBinding.associationPathName) && !this.peekInlineFieldSettingsOpenView(inlineSettings, boundFieldCapability.wrapperUse)) {
4927
5140
  inlinePopup = this.normalizeInlinePopup("addField", {
4928
5141
  tryTemplate: true,
4929
- defaultType: "view"
5142
+ defaultType: "view",
5143
+ ...values[import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY] ? {
5144
+ [import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY]: values[import_defaults.FLOW_SURFACE_APPLY_BLUEPRINT_POPUP_DEFAULTS_KEY]
5145
+ } : {}
4930
5146
  });
4931
5147
  }
4932
5148
  if (inlinePopup && this.isExternalPopupOpenView(
@@ -5046,6 +5262,24 @@ class FlowSurfacesService {
5046
5262
  containerUse: container.ownerUse,
5047
5263
  context: "addAction"
5048
5264
  });
5265
+ const reusableAction = await this.resolveReusableSingletonAction({
5266
+ parentUid: container.parentUid,
5267
+ ownerUse: container.ownerUse,
5268
+ actionUse: actionCatalogItem.use,
5269
+ transaction: options.transaction
5270
+ });
5271
+ if (reusableAction == null ? void 0 : reusableAction.uid) {
5272
+ await this.applyInlineNodeSettings("addAction", reusableAction.uid, inlineSettings, options);
5273
+ const result2 = {
5274
+ uid: reusableAction.uid,
5275
+ parentUid: container.parentUid,
5276
+ subKey: container.subKey,
5277
+ scope: actionCatalogItem.scope,
5278
+ ...await this.collectComposeActionKeys(reusableAction.uid, options.transaction)
5279
+ };
5280
+ await this.persistCreatedKeysForAction("addAction", values, result2, options.transaction);
5281
+ return result2;
5282
+ }
5049
5283
  const resourceContext = container.ownerUid ? await this.locator.resolveCollectionContext(container.ownerUid, options.transaction).catch(() => null) : null;
5050
5284
  const action = (0, import_builder.buildActionTree)({
5051
5285
  use: actionCatalogItem.use,
@@ -5446,9 +5680,6 @@ class FlowSurfacesService {
5446
5680
  if (saveAsTemplate && !import_lodash.default.isUndefined(normalizedPopup.template)) {
5447
5681
  (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} popup.saveAsTemplate cannot be combined with popup.template`);
5448
5682
  }
5449
- if (saveAsTemplate && !import_lodash.default.isUndefined(tryTemplate)) {
5450
- (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} popup.saveAsTemplate cannot be combined with popup.tryTemplate`);
5451
- }
5452
5683
  if (import_lodash.default.isUndefined(tryTemplate)) {
5453
5684
  delete normalizedPopup.tryTemplate;
5454
5685
  } else {
@@ -5502,17 +5733,17 @@ class FlowSurfacesService {
5502
5733
  };
5503
5734
  }
5504
5735
  formatAutoGeneratedPopupTemplateMetadata(input) {
5505
- const popupLabel = input.defaultType === "edit" ? "edit popup" : "details popup";
5736
+ const popupLabel = input.defaultType === "edit" ? "Popup for Edit" : "Popup for Details";
5506
5737
  return {
5507
5738
  name: `${input.sourceCollectionLabel} -> ${input.associationFieldLabel} ${popupLabel} (Auto generated)`,
5508
- description: `Automatically generated ${popupLabel} template for relation field '${input.associationFieldLabel}' in collection '${input.sourceCollectionLabel}', targeting '${input.targetCollectionLabel}'.`
5739
+ description: `Automatically generated popup template for relation field "${input.associationFieldLabel}" in collection "${input.sourceCollectionLabel}", targeting "${input.targetCollectionLabel}" (${popupLabel}).`
5509
5740
  };
5510
5741
  }
5511
5742
  formatAutoGeneratedActionPopupTemplateMetadata(input) {
5512
- const popupLabel = input.popupType === "addNew" ? "create popup" : input.popupType === "edit" ? "edit popup" : "details popup";
5743
+ const popupLabel = input.popupType === "addNew" ? "Popup for Add New" : input.popupType === "edit" ? "Popup for Edit" : "Popup for Details";
5513
5744
  return {
5514
5745
  name: `${input.collectionLabel} ${popupLabel} (Auto generated)`,
5515
- description: `Automatically generated ${popupLabel} template for collection '${input.collectionLabel}'.`
5746
+ description: `Automatically generated popup template for collection "${input.collectionLabel}" (${popupLabel}).`
5516
5747
  };
5517
5748
  }
5518
5749
  resolveFieldBindingContext(fieldNode, wrapperNode) {
@@ -5562,11 +5793,21 @@ class FlowSurfacesService {
5562
5793
  if (!bindingContext.associationField || !bindingContext.targetCollection) {
5563
5794
  return fallback;
5564
5795
  }
5565
- const sourceCollectionLabel = String((0, import_service_helpers.getCollectionTitle)(bindingContext.sourceCollection) || "").trim() || bindingContext.collectionName;
5796
+ const sourceCollectionLabel = String(
5797
+ (0, import_template_display.compileTemplateString)(
5798
+ (0, import_service_helpers.getCollectionTitle)(bindingContext.sourceCollection) || bindingContext.collectionName || ""
5799
+ ) || ""
5800
+ ).trim();
5566
5801
  const associationFieldLabel = String(
5567
- (0, import_service_helpers.getFieldTitle)(bindingContext.associationField) || (0, import_service_helpers.getFieldName)(bindingContext.associationField) || ""
5568
- ).trim() || String((0, import_service_helpers.getFieldName)(bindingContext.associationField) || "").trim();
5569
- const targetCollectionLabel = String((0, import_service_helpers.getCollectionTitle)(bindingContext.targetCollection) || "").trim() || String((0, import_service_helpers.getCollectionName)(bindingContext.targetCollection) || "").trim();
5802
+ (0, import_template_display.compileTemplateString)(
5803
+ (0, import_service_helpers.getFieldTitle)(bindingContext.associationField) || (0, import_service_helpers.getFieldName)(bindingContext.associationField) || ""
5804
+ ) || ""
5805
+ ).trim();
5806
+ const targetCollectionLabel = String(
5807
+ (0, import_template_display.compileTemplateString)(
5808
+ (0, import_service_helpers.getCollectionTitle)(bindingContext.targetCollection) || (0, import_service_helpers.getCollectionName)(bindingContext.targetCollection) || ""
5809
+ ) || ""
5810
+ ).trim();
5570
5811
  if (!sourceCollectionLabel || !associationFieldLabel || !targetCollectionLabel) {
5571
5812
  return fallback;
5572
5813
  }
@@ -5583,6 +5824,32 @@ class FlowSurfacesService {
5583
5824
  shouldAutoSaveDefaultActionPopupTemplate(popup) {
5584
5825
  return (popup == null ? void 0 : popup[import_default_block_actions.FLOW_SURFACE_INTERNAL_AUTO_SAVE_DEFAULT_POPUP_TEMPLATE_KEY]) === true;
5585
5826
  }
5827
+ shouldImplicitlyTemplateDefaultActionPopup(actionNode, popup) {
5828
+ if (!(0, import_default_action_popup.isFlowSurfaceDefaultActionPopupUse)(actionNode == null ? void 0 : actionNode.use)) {
5829
+ return false;
5830
+ }
5831
+ if (import_lodash.default.isPlainObject(popup == null ? void 0 : popup.template) || !import_lodash.default.isUndefined(popup == null ? void 0 : popup.saveAsTemplate)) {
5832
+ return false;
5833
+ }
5834
+ if ((popup == null ? void 0 : popup.tryTemplate) === false) {
5835
+ return false;
5836
+ }
5837
+ if ((0, import_default_action_popup.hasFlowSurfaceInlinePopupBlocks)(popup)) {
5838
+ return false;
5839
+ }
5840
+ return true;
5841
+ }
5842
+ buildImplicitTemplateDefaultActionPopup(actionNode, popup) {
5843
+ if (!this.shouldImplicitlyTemplateDefaultActionPopup(actionNode, popup)) {
5844
+ return popup;
5845
+ }
5846
+ const nextPopup = import_lodash.default.isPlainObject(popup) ? import_lodash.default.cloneDeep(popup) : {};
5847
+ if (import_lodash.default.isUndefined(nextPopup.tryTemplate)) {
5848
+ nextPopup.tryTemplate = true;
5849
+ }
5850
+ nextPopup[import_default_block_actions.FLOW_SURFACE_INTERNAL_AUTO_SAVE_DEFAULT_POPUP_TEMPLATE_KEY] = true;
5851
+ return nextPopup;
5852
+ }
5586
5853
  async resolveAutoGeneratedActionPopupTemplateMetadata(actionUid, identity, transaction) {
5587
5854
  const fallback = this.buildLegacyAutoGeneratedPopupTemplateMetadata(identity);
5588
5855
  try {
@@ -5593,7 +5860,11 @@ class FlowSurfacesService {
5593
5860
  const actionConfig = (0, import_default_action_popup.getFlowSurfaceDefaultActionPopupConfigByUse)(actionNode == null ? void 0 : actionNode.use);
5594
5861
  const popupProfile = (actionNode == null ? void 0 : actionNode.uid) ? await this.resolvePopupBlockProfile(actionNode.uid, null, actionNode, transaction).catch(() => null) : null;
5595
5862
  const popupType = actionConfig == null ? void 0 : actionConfig.type;
5596
- const collectionLabel = String((0, import_service_helpers.getCollectionTitle)(popupProfile == null ? void 0 : popupProfile.currentCollection) || "").trim() || String((popupProfile == null ? void 0 : popupProfile.collectionName) || "").trim();
5863
+ const collectionLabel = String(
5864
+ (0, import_template_display.compileTemplateString)(
5865
+ (0, import_service_helpers.getCollectionTitle)(popupProfile == null ? void 0 : popupProfile.currentCollection) || (popupProfile == null ? void 0 : popupProfile.collectionName) || ""
5866
+ ) || ""
5867
+ ).trim();
5597
5868
  if (!popupType || !collectionLabel) {
5598
5869
  return fallback;
5599
5870
  }
@@ -5623,8 +5894,25 @@ class FlowSurfacesService {
5623
5894
  options
5624
5895
  );
5625
5896
  }
5626
- buildInlinePopupTemplateOpenView(popup) {
5627
- const normalizedTitle = import_lodash.default.isUndefined(popup == null ? void 0 : popup.title) || import_lodash.default.isNull(popup == null ? void 0 : popup.title) ? void 0 : String(popup.title).trim() || void 0;
5897
+ normalizeOptionalPopupTitle(value) {
5898
+ if (import_lodash.default.isUndefined(value) || import_lodash.default.isNull(value)) {
5899
+ return void 0;
5900
+ }
5901
+ const normalizedTitle = String(value).trim();
5902
+ return normalizedTitle || void 0;
5903
+ }
5904
+ resolveDefaultActionPopupTemplateOpenViewTitle(actionNode, popup) {
5905
+ const explicitTitle = this.normalizeOptionalPopupTitle(popup == null ? void 0 : popup.title);
5906
+ if (explicitTitle) {
5907
+ return explicitTitle;
5908
+ }
5909
+ if (!(0, import_default_action_popup.isFlowSurfaceDefaultActionPopupUse)(actionNode == null ? void 0 : actionNode.use)) {
5910
+ return void 0;
5911
+ }
5912
+ return (0, import_default_action_popup.resolveFlowSurfaceDefaultActionPopupTabTitle)(actionNode == null ? void 0 : actionNode.use, this.getActionButtonTitle(actionNode));
5913
+ }
5914
+ buildInlinePopupTemplateOpenView(popup, fallbackTitle) {
5915
+ const normalizedTitle = this.normalizeOptionalPopupTitle(popup == null ? void 0 : popup.title) || this.normalizeOptionalPopupTitle(fallbackTitle);
5628
5916
  return (0, import_service_utils.buildDefinedPayload)({
5629
5917
  template: popup == null ? void 0 : popup.template,
5630
5918
  title: normalizedTitle
@@ -5768,7 +6056,8 @@ class FlowSurfacesService {
5768
6056
  return actionConfig.type === "view" ? ["view", "generic"] : [actionConfig.type];
5769
6057
  }
5770
6058
  if (POPUP_ACTION_USES.has(targetUse)) {
5771
- return (popupActionContext == null ? void 0 : popupActionContext.hasCurrentRecord) ? ["view", "generic"] : ["generic"];
6059
+ const hasCurrentRecord = (popupActionContext == null ? void 0 : popupActionContext.hasCurrentRecord) || targetUse === "CalendarEventViewActionModel";
6060
+ return hasCurrentRecord ? ["view", "generic"] : ["generic"];
5772
6061
  }
5773
6062
  return void 0;
5774
6063
  }
@@ -5919,6 +6208,12 @@ class FlowSurfacesService {
5919
6208
  popupTemplateUid: template.uid
5920
6209
  };
5921
6210
  }
6211
+ isReferencedPopupTemplateOpenView(openView, hostUid) {
6212
+ return !!this.resolveExternalPopupHostUid(hostUid, openView) && !!String((openView == null ? void 0 : openView.popupTemplateUid) || "").trim() && !(openView == null ? void 0 : openView.popupTemplateContext);
6213
+ }
6214
+ isEditableDefaultActionPopupTemplateReference(hostNode, openView) {
6215
+ return (0, import_default_action_popup.isFlowSurfaceDefaultActionPopupUse)(hostNode == null ? void 0 : hostNode.use) && this.isReferencedPopupTemplateOpenView(openView, hostNode == null ? void 0 : hostNode.uid);
6216
+ }
5922
6217
  resolveExternalPopupHostUid(hostUid, openView) {
5923
6218
  const normalizedHostUid = String(hostUid || "").trim();
5924
6219
  if (!normalizedHostUid || !import_lodash.default.isPlainObject(openView)) {
@@ -6058,7 +6353,7 @@ class FlowSurfacesService {
6058
6353
  return void 0;
6059
6354
  }
6060
6355
  const hostContext = await this.resolvePopupHostProfileContext(current, transaction).catch(() => null);
6061
- if (!(hostContext == null ? void 0 : hostContext.recordActionContainerUse)) {
6356
+ if (!this.popupHostUsesDefaultRecordContext(current, hostContext)) {
6062
6357
  return void 0;
6063
6358
  }
6064
6359
  return {
@@ -6265,13 +6560,14 @@ class FlowSurfacesService {
6265
6560
  }
6266
6561
  )
6267
6562
  );
6563
+ this.registerInlinePopupTemplateAlias(actionName, popup, matchedTemplate, options.popupTemplateAliasSession);
6268
6564
  return;
6269
6565
  }
6270
6566
  try {
6271
6567
  if (!popup || !fieldHostUid) {
6272
6568
  return;
6273
6569
  }
6274
- const { fieldNode, wrapperNode } = await this.loadFieldHostNodes(fieldHostUid, options.transaction);
6570
+ let { fieldNode, wrapperNode } = await this.loadFieldHostNodes(fieldHostUid, options.transaction);
6275
6571
  this.assertInlinePopupSaveAsTemplateSource(actionName, popup);
6276
6572
  const hasLocalPopupContent = (0, import_default_action_popup.hasFlowSurfaceInlinePopupBlocks)(popup) || !import_lodash.default.isUndefined(popup.layout);
6277
6573
  if (popup.tryTemplate && !hasLocalPopupContent && !this.shouldAutoCompleteDefaultFieldPopup(fieldNode, popup)) {
@@ -6280,15 +6576,33 @@ class FlowSurfacesService {
6280
6576
  const shouldAutoCompleteDefaultPopup = this.shouldAutoCompleteDefaultFieldPopup(fieldNode, popup);
6281
6577
  Object.assign(result, await this.ensureLocalFieldPopupSurface(actionName, fieldHostUid, options, { popup }));
6282
6578
  if (shouldAutoCompleteDefaultPopup) {
6579
+ const reloaded = await this.loadFieldHostNodes(fieldHostUid, options.transaction);
6580
+ fieldNode = reloaded.fieldNode;
6581
+ wrapperNode = reloaded.wrapperNode;
6283
6582
  const popupContext = this.resolveFieldOpenViewContext(fieldNode, wrapperNode);
6284
6583
  const defaultType = this.getRequestedPopupDefaultType(popup) || "view";
6584
+ await this.syncDefaultFieldPopupOpenViewTitle(
6585
+ fieldHostUid,
6586
+ fieldNode,
6587
+ wrapperNode,
6588
+ popup,
6589
+ defaultType,
6590
+ popupContext,
6591
+ options
6592
+ );
6285
6593
  await this.compose(
6286
6594
  {
6287
6595
  target: {
6288
6596
  uid: fieldHostUid
6289
6597
  },
6290
6598
  mode: popup.mode || "replace",
6291
- blocks: this.buildDefaultFieldPopupBlocks(fieldNode, popupContext, defaultType, options.enabledPackages),
6599
+ blocks: this.buildDefaultFieldPopupBlocks(
6600
+ fieldNode,
6601
+ popupContext,
6602
+ defaultType,
6603
+ popup,
6604
+ options.enabledPackages
6605
+ ),
6292
6606
  layout: popup.layout
6293
6607
  },
6294
6608
  options
@@ -6382,6 +6696,9 @@ class FlowSurfacesService {
6382
6696
  }
6383
6697
  return !(0, import_default_action_popup.hasFlowSurfaceInlinePopupTemplate)(popup) && !(0, import_default_action_popup.hasFlowSurfaceInlinePopupBlocks)(popup);
6384
6698
  }
6699
+ isEmptyInlinePopupPayload(popup) {
6700
+ return import_lodash.default.isPlainObject(popup) && Object.keys(popup).length === 0;
6701
+ }
6385
6702
  shouldAutoCompleteDefaultFieldPopup(fieldNode, popup) {
6386
6703
  if (!import_lodash.default.isPlainObject(popup)) {
6387
6704
  return false;
@@ -6398,7 +6715,79 @@ class FlowSurfacesService {
6398
6715
  }
6399
6716
  return popup.tryTemplate === true || !import_lodash.default.isUndefined(popup.defaultType) || Object.keys(popup).length === 0;
6400
6717
  }
6401
- buildDefaultFieldPopupFieldPaths(input) {
6718
+ getApplyBlueprintPopupDefaultsMetadata(popup) {
6719
+ return (0, import_defaults.readFlowSurfaceApplyBlueprintPopupDefaultsMetadata)(popup);
6720
+ }
6721
+ getApplyBlueprintDefaultFieldGroups(popup, collectionName) {
6722
+ var _a;
6723
+ return (_a = (0, import_defaults.getFlowSurfaceApplyBlueprintDefaultCollection)(
6724
+ this.getApplyBlueprintPopupDefaultsMetadata(popup),
6725
+ collectionName
6726
+ )) == null ? void 0 : _a.fieldGroups;
6727
+ }
6728
+ pickDefaultPopupFields(input) {
6729
+ const defaultFieldGroups = this.getApplyBlueprintDefaultFieldGroups(input.popup, input.collectionName);
6730
+ if (defaultFieldGroups) {
6731
+ return {
6732
+ fieldGroups: (0, import_default_action_popup.pickFlowSurfaceDefaultActionPopupFieldGroups)(
6733
+ input.candidates,
6734
+ defaultFieldGroups,
6735
+ input.options
6736
+ )
6737
+ };
6738
+ }
6739
+ return {
6740
+ fieldPaths: (0, import_default_action_popup.pickFlowSurfaceDefaultActionPopupFieldPaths)(input.candidates, input.options)
6741
+ };
6742
+ }
6743
+ resolveApplyBlueprintDefaultPopupMetadata(input) {
6744
+ return (0, import_defaults.resolveFlowSurfaceApplyBlueprintDefaultPopupMetadata)({
6745
+ metadata: this.getApplyBlueprintPopupDefaultsMetadata(input.popup),
6746
+ actionType: input.actionType,
6747
+ sourceCollectionName: input.sourceCollectionName,
6748
+ associationField: input.associationField,
6749
+ targetCollectionName: input.targetCollectionName
6750
+ });
6751
+ }
6752
+ resolveApplyBlueprintAssociationDefaultContext(associationName) {
6753
+ const parts = String(associationName || "").trim().split(".").map((part) => part.trim()).filter(Boolean);
6754
+ if (parts.length < 2) {
6755
+ return {};
6756
+ }
6757
+ const [sourceCollectionName, ...associationFieldParts] = parts;
6758
+ return {
6759
+ sourceCollectionName,
6760
+ associationField: associationFieldParts.join(".")
6761
+ };
6762
+ }
6763
+ resolveGeneratedDefaultFieldPopupName(input) {
6764
+ var _a;
6765
+ const defaultPopupMetadata = this.resolveGeneratedDefaultFieldPopupMetadata(input);
6766
+ if (defaultPopupMetadata == null ? void 0 : defaultPopupMetadata.name) {
6767
+ return defaultPopupMetadata.name;
6768
+ }
6769
+ const explicitTitle = this.normalizeOptionalPopupTitle((_a = input.popup) == null ? void 0 : _a.title);
6770
+ if (explicitTitle) {
6771
+ return explicitTitle;
6772
+ }
6773
+ return void 0;
6774
+ }
6775
+ resolveGeneratedDefaultFieldPopupMetadata(input) {
6776
+ var _a, _b;
6777
+ const explicitTitle = this.normalizeOptionalPopupTitle((_a = input.popup) == null ? void 0 : _a.title);
6778
+ if (explicitTitle) {
6779
+ return void 0;
6780
+ }
6781
+ const bindingContext = this.resolveFieldBindingContext(input.fieldNode, input.wrapperNode);
6782
+ return this.resolveApplyBlueprintDefaultPopupMetadata({
6783
+ popup: input.popup,
6784
+ actionType: input.defaultType,
6785
+ sourceCollectionName: bindingContext.collectionName,
6786
+ associationField: (0, import_service_helpers.normalizeFieldPath)(bindingContext.fieldPath || "", bindingContext.associationPathName),
6787
+ targetCollectionName: bindingContext.targetCollectionName || String(((_b = input.popupContext) == null ? void 0 : _b.collectionName) || "")
6788
+ });
6789
+ }
6790
+ buildDefaultFieldPopupFields(input) {
6402
6791
  const collectionName = String(input.popupContext.collectionName || "").trim();
6403
6792
  if (!collectionName) {
6404
6793
  return [];
@@ -6414,12 +6803,17 @@ class FlowSurfacesService {
6414
6803
  },
6415
6804
  enabledPackages: input.enabledPackages
6416
6805
  });
6417
- return (0, import_default_action_popup.pickFlowSurfaceDefaultActionPopupFieldPaths)(directCandidates, {
6418
- excludeAuditTimestampFields: input.defaultType === "edit",
6419
- excludeAssociationFields: true
6806
+ return this.pickDefaultPopupFields({
6807
+ candidates: directCandidates,
6808
+ popup: input.popup,
6809
+ collectionName,
6810
+ options: {
6811
+ excludeAuditTimestampFields: input.defaultType === "edit",
6812
+ excludeAssociationFields: true
6813
+ }
6420
6814
  });
6421
6815
  }
6422
- buildDefaultFieldPopupBlocks(fieldNode, popupContext, defaultType, enabledPackages) {
6816
+ buildDefaultFieldPopupBlocks(fieldNode, popupContext, defaultType, popup, enabledPackages) {
6423
6817
  var _a;
6424
6818
  const actionUse = defaultType === "edit" ? "EditActionModel" : "ViewActionModel";
6425
6819
  const namespace = (0, import_service_utils.normalizeFlowSurfaceComposeKey)(
@@ -6434,18 +6828,54 @@ class FlowSurfacesService {
6434
6828
  if ((_a = actionConfig == null ? void 0 : actionConfig.submitAction) == null ? void 0 : _a.key) {
6435
6829
  keyMap.set(actionConfig.submitAction.key, `${namespace}.${actionConfig.submitAction.key}`);
6436
6830
  }
6437
- const fieldPaths = this.buildDefaultFieldPopupFieldPaths({
6831
+ const fields = this.buildDefaultFieldPopupFields({
6438
6832
  defaultType,
6439
6833
  fieldNode,
6834
+ popup,
6440
6835
  popupContext,
6441
6836
  enabledPackages
6442
6837
  });
6443
6838
  return this.remapDefaultActionPopupBlocks(
6444
- (0, import_default_action_popup.buildFlowSurfaceDefaultActionPopupBlocks)(actionUse, fieldPaths),
6839
+ (0, import_default_action_popup.buildFlowSurfaceDefaultActionPopupBlocks)(actionUse, fields),
6445
6840
  keyMap,
6446
6841
  namespace
6447
6842
  );
6448
6843
  }
6844
+ async syncDefaultFieldPopupOpenViewTitle(fieldHostUid, fieldNode, wrapperNode, popup, defaultType, popupContext, options) {
6845
+ const normalizedFieldHostUid = String(fieldHostUid || "").trim();
6846
+ if (!normalizedFieldHostUid) {
6847
+ return;
6848
+ }
6849
+ const openViewTitle = this.resolveGeneratedDefaultFieldPopupName({
6850
+ fieldNode,
6851
+ wrapperNode,
6852
+ popup,
6853
+ defaultType,
6854
+ popupContext
6855
+ });
6856
+ if (!openViewTitle) {
6857
+ return;
6858
+ }
6859
+ const currentOpenView = this.resolvePopupHostOpenView(fieldNode);
6860
+ if (this.normalizeOptionalPopupTitle(currentOpenView == null ? void 0 : currentOpenView.title) === openViewTitle) {
6861
+ return;
6862
+ }
6863
+ await this.configureFieldNode(
6864
+ {
6865
+ uid: normalizedFieldHostUid
6866
+ },
6867
+ {
6868
+ openView: {
6869
+ ...import_lodash.default.isPlainObject(currentOpenView) ? currentOpenView : {},
6870
+ title: openViewTitle
6871
+ }
6872
+ },
6873
+ {
6874
+ ...options,
6875
+ openViewActionName: "addField"
6876
+ }
6877
+ );
6878
+ }
6449
6879
  async autoSaveDefaultFieldPopupAsTemplate(result, popup, options) {
6450
6880
  if (!this.getFlowTemplateRepositorySafe()) {
6451
6881
  return;
@@ -6474,6 +6904,20 @@ class FlowSurfacesService {
6474
6904
  );
6475
6905
  const identity = (0, import_crypto.createHash)("sha1").update(uniqueKeySource).digest("hex").slice(0, 12);
6476
6906
  const defaultType = this.getRequestedPopupDefaultType(popup) || "view";
6907
+ const resolvedDefaultMetadata = await (async () => {
6908
+ try {
6909
+ const { fieldNode, wrapperNode } = await this.loadFieldHostNodes(fieldHostUid, options.transaction);
6910
+ return this.resolveGeneratedDefaultFieldPopupMetadata({
6911
+ fieldNode,
6912
+ wrapperNode,
6913
+ popup,
6914
+ defaultType,
6915
+ popupContext: openView
6916
+ });
6917
+ } catch {
6918
+ return void 0;
6919
+ }
6920
+ })();
6477
6921
  const metadata = await this.resolveAutoGeneratedFieldPopupTemplateMetadata(
6478
6922
  fieldHostUid,
6479
6923
  defaultType,
@@ -6485,15 +6929,15 @@ class FlowSurfacesService {
6485
6929
  target: {
6486
6930
  uid: fieldHostUid
6487
6931
  },
6488
- name: metadata.name,
6489
- description: metadata.description,
6932
+ name: (resolvedDefaultMetadata == null ? void 0 : resolvedDefaultMetadata.name) || metadata.name,
6933
+ description: (resolvedDefaultMetadata == null ? void 0 : resolvedDefaultMetadata.description) || metadata.description,
6490
6934
  saveMode: "convert"
6491
6935
  },
6492
6936
  options
6493
6937
  );
6494
6938
  this.clearPopupSurfaceKeys(result);
6495
6939
  }
6496
- async autoSaveDefaultActionPopupAsTemplate(actionUid, _popup, options) {
6940
+ async autoSaveDefaultActionPopupAsTemplate(actionUid, popup, options) {
6497
6941
  if (!this.getFlowTemplateRepositorySafe()) {
6498
6942
  return;
6499
6943
  }
@@ -6524,6 +6968,8 @@ class FlowSurfacesService {
6524
6968
  })
6525
6969
  );
6526
6970
  const identity = (0, import_crypto.createHash)("sha1").update(uniqueKeySource).digest("hex").slice(0, 12);
6971
+ const popupProfile = (actionNode == null ? void 0 : actionNode.uid) ? await this.resolvePopupBlockProfile(actionNode.uid, null, actionNode, options.transaction).catch(() => null) : null;
6972
+ const resolvedDefaultMetadata = this.resolveGeneratedDefaultActionPopupMetadata(actionNode, popup, popupProfile);
6527
6973
  const metadata = await this.resolveAutoGeneratedActionPopupTemplateMetadata(
6528
6974
  actionUid,
6529
6975
  identity,
@@ -6534,12 +6980,16 @@ class FlowSurfacesService {
6534
6980
  target: {
6535
6981
  uid: actionUid
6536
6982
  },
6537
- name: metadata.name,
6538
- description: metadata.description,
6983
+ name: (resolvedDefaultMetadata == null ? void 0 : resolvedDefaultMetadata.name) || metadata.name,
6984
+ description: (resolvedDefaultMetadata == null ? void 0 : resolvedDefaultMetadata.description) || metadata.description,
6539
6985
  saveMode: "convert"
6540
6986
  },
6541
6987
  options
6542
6988
  );
6989
+ await this.syncDefaultActionPopupOpenViewTitle(actionUid, actionNode, {
6990
+ ...options,
6991
+ openViewTitle: this.resolveGeneratedDefaultActionPopupName(actionNode, popup, popupProfile) || this.resolveDefaultActionPopupTemplateOpenViewTitle(actionNode, popup)
6992
+ });
6543
6993
  }
6544
6994
  shouldAutoCompleteDefaultActionPopup(actionNode, popup, options = {}) {
6545
6995
  if (options.autoCompleteDefaultPopup === false) {
@@ -6557,7 +7007,41 @@ class FlowSurfacesService {
6557
7007
  }
6558
7008
  return true;
6559
7009
  }
6560
- buildDefaultActionPopupFieldPaths(input) {
7010
+ resolveGeneratedDefaultActionPopupName(actionNode, popup, popupProfile, options = {}) {
7011
+ const defaultPopupMetadata = this.resolveGeneratedDefaultActionPopupMetadata(actionNode, popup, popupProfile);
7012
+ if (defaultPopupMetadata == null ? void 0 : defaultPopupMetadata.name) {
7013
+ return defaultPopupMetadata.name;
7014
+ }
7015
+ const explicitTitle = this.normalizeOptionalPopupTitle(popup == null ? void 0 : popup.title);
7016
+ if (explicitTitle) {
7017
+ return explicitTitle;
7018
+ }
7019
+ if (options.includeFallback === false) {
7020
+ return void 0;
7021
+ }
7022
+ return (0, import_default_action_popup.resolveFlowSurfaceDefaultActionPopupTabTitle)(actionNode == null ? void 0 : actionNode.use, this.getActionButtonTitle(actionNode));
7023
+ }
7024
+ resolveGeneratedDefaultActionPopupMetadata(actionNode, popup, popupProfile) {
7025
+ const explicitTitle = this.normalizeOptionalPopupTitle(popup == null ? void 0 : popup.title);
7026
+ if (explicitTitle) {
7027
+ return void 0;
7028
+ }
7029
+ const actionConfig = (0, import_default_action_popup.getFlowSurfaceDefaultActionPopupConfigByUse)(actionNode == null ? void 0 : actionNode.use);
7030
+ if (!actionConfig) {
7031
+ return void 0;
7032
+ }
7033
+ const associationDefaultContext = this.resolveApplyBlueprintAssociationDefaultContext(
7034
+ popupProfile == null ? void 0 : popupProfile.associationName
7035
+ );
7036
+ return this.resolveApplyBlueprintDefaultPopupMetadata({
7037
+ popup,
7038
+ actionType: actionConfig.type,
7039
+ sourceCollectionName: associationDefaultContext.sourceCollectionName,
7040
+ associationField: associationDefaultContext.associationField,
7041
+ targetCollectionName: popupProfile == null ? void 0 : popupProfile.collectionName
7042
+ });
7043
+ }
7044
+ buildDefaultActionPopupFields(input) {
6561
7045
  var _a, _b;
6562
7046
  const collectionName = String(((_a = input.popupProfile) == null ? void 0 : _a.collectionName) || "").trim();
6563
7047
  if (!collectionName) {
@@ -6577,8 +7061,13 @@ class FlowSurfacesService {
6577
7061
  },
6578
7062
  enabledPackages: input.enabledPackages
6579
7063
  });
6580
- return (0, import_default_action_popup.pickFlowSurfaceDefaultActionPopupFieldPaths)(directCandidates, {
6581
- excludeAuditTimestampFields: mode === "form"
7064
+ return this.pickDefaultPopupFields({
7065
+ candidates: directCandidates,
7066
+ popup: input.popup,
7067
+ collectionName,
7068
+ options: {
7069
+ excludeAuditTimestampFields: mode === "form"
7070
+ }
6582
7071
  });
6583
7072
  }
6584
7073
  buildDefaultActionPopupNamespace(actionNode) {
@@ -6649,11 +7138,32 @@ class FlowSurfacesService {
6649
7138
  `flowSurfaces default popup block '${blockKey || (block == null ? void 0 : block.type) || "unknown"}' field #${fieldIndex + 1}`
6650
7139
  );
6651
7140
  });
7141
+ const remappedFieldGroups = import_lodash.default.castArray((block == null ? void 0 : block.fieldGroups) || []).map((group, groupIndex) => {
7142
+ if (!namespace || !import_lodash.default.isPlainObject(group)) {
7143
+ return import_lodash.default.cloneDeep(group);
7144
+ }
7145
+ const rawGroupKey = typeof group.key === "string" && group.key.trim() || typeof group.title === "string" && group.title.trim() || `group_${groupIndex + 1}`;
7146
+ return {
7147
+ ...import_lodash.default.cloneDeep(group),
7148
+ key: (0, import_service_utils.normalizeFlowSurfaceComposeKey)(
7149
+ `${namespace}.${rawGroupKey}`,
7150
+ `flowSurfaces default popup block '${blockKey || (block == null ? void 0 : block.type) || "unknown"}' fieldGroup #${groupIndex + 1}`
7151
+ ),
7152
+ fields: import_lodash.default.castArray(group.fields || []).map(
7153
+ (field, fieldIndex) => this.remapDefaultActionPopupField(
7154
+ field,
7155
+ namespace,
7156
+ `flowSurfaces default popup block '${blockKey || (block == null ? void 0 : block.type) || "unknown"}' fieldGroup #${groupIndex + 1} field #${fieldIndex + 1}`
7157
+ )
7158
+ )
7159
+ };
7160
+ });
6652
7161
  return import_lodash.default.pickBy(
6653
7162
  {
6654
7163
  ...import_lodash.default.cloneDeep(block),
6655
7164
  key: blockKey && keyMap.has(blockKey) ? keyMap.get(blockKey) : block == null ? void 0 : block.key,
6656
7165
  fields: remappedFields.length ? remappedFields : void 0,
7166
+ fieldGroups: remappedFieldGroups.length ? remappedFieldGroups : void 0,
6657
7167
  actions: remappedActions.length ? remappedActions : void 0
6658
7168
  },
6659
7169
  (value) => !import_lodash.default.isUndefined(value)
@@ -6685,14 +7195,15 @@ class FlowSurfacesService {
6685
7195
  );
6686
7196
  return nextLayout;
6687
7197
  }
6688
- buildDefaultActionPopupBlocks(actionNode, popupProfile, keyMap, namespace, enabledPackages) {
6689
- const fieldPaths = this.buildDefaultActionPopupFieldPaths({
7198
+ buildDefaultActionPopupBlocks(actionNode, popupProfile, popup, keyMap, namespace, enabledPackages) {
7199
+ const fields = this.buildDefaultActionPopupFields({
6690
7200
  actionUse: actionNode == null ? void 0 : actionNode.use,
6691
7201
  popupProfile,
7202
+ popup,
6692
7203
  enabledPackages
6693
7204
  });
6694
7205
  return this.remapDefaultActionPopupBlocks(
6695
- (0, import_default_action_popup.buildFlowSurfaceDefaultActionPopupBlocks)(actionNode == null ? void 0 : actionNode.use, fieldPaths),
7206
+ (0, import_default_action_popup.buildFlowSurfaceDefaultActionPopupBlocks)(actionNode == null ? void 0 : actionNode.use, fields),
6696
7207
  keyMap,
6697
7208
  namespace
6698
7209
  );
@@ -6705,7 +7216,7 @@ class FlowSurfacesService {
6705
7216
  uid: actionNode.uid
6706
7217
  },
6707
7218
  mode: (popup == null ? void 0 : popup.mode) || "replace",
6708
- blocks: this.buildDefaultActionPopupBlocks(actionNode, popupProfile, keyMap, namespace, enabledPackages),
7219
+ blocks: this.buildDefaultActionPopupBlocks(actionNode, popupProfile, popup, keyMap, namespace, enabledPackages),
6709
7220
  layout: this.remapDefaultActionPopupLayout(popup == null ? void 0 : popup.layout, keyMap)
6710
7221
  };
6711
7222
  }
@@ -6762,10 +7273,7 @@ class FlowSurfacesService {
6762
7273
  return normalizedTitle || void 0;
6763
7274
  }
6764
7275
  async syncDefaultActionPopupTabTitle(actionNode, popupTab, options) {
6765
- const popupTabTitle = (0, import_default_action_popup.resolveFlowSurfaceDefaultActionPopupTabTitle)(
6766
- actionNode == null ? void 0 : actionNode.use,
6767
- this.getActionButtonTitle(actionNode)
6768
- );
7276
+ const popupTabTitle = this.normalizeOptionalPopupTitle(options.popupTabTitle) || (0, import_default_action_popup.resolveFlowSurfaceDefaultActionPopupTabTitle)(actionNode == null ? void 0 : actionNode.use, this.getActionButtonTitle(actionNode));
6769
7277
  if (!(popupTab == null ? void 0 : popupTab.uid) || !popupTabTitle || this.resolvePopupTabTitle(popupTab) === popupTabTitle) {
6770
7278
  return;
6771
7279
  }
@@ -6779,54 +7287,186 @@ class FlowSurfacesService {
6779
7287
  options
6780
7288
  );
6781
7289
  }
6782
- async applyDefaultActionPopupContent(actionNode, popup, options) {
6783
- const popupProfile = await this.resolvePopupBlockProfile(actionNode.uid, null, actionNode, options.transaction);
6784
- if (!(popupProfile == null ? void 0 : popupProfile.isPopupSurface)) {
7290
+ async syncDefaultActionPopupTabTitleForHost(actionNode, popupHostUid, options) {
7291
+ var _a, _b;
7292
+ const normalizedPopupHostUid = String(popupHostUid || "").trim();
7293
+ if (!normalizedPopupHostUid) {
6785
7294
  return;
6786
7295
  }
6787
- await this.compose(
6788
- this.buildDefaultActionPopupComposeValues(actionNode, popupProfile, popup, options.enabledPackages),
7296
+ const popupHost = await this.repository.findModelById(normalizedPopupHostUid, {
7297
+ transaction: options.transaction,
7298
+ includeAsyncNode: true
7299
+ });
7300
+ const popupPage = (0, import_service_utils.getSingleNodeSubModel)((_a = popupHost == null ? void 0 : popupHost.subModels) == null ? void 0 : _a.page);
7301
+ const popupTab = import_lodash.default.castArray(((_b = popupPage == null ? void 0 : popupPage.subModels) == null ? void 0 : _b.tabs) || [])[0];
7302
+ const popupTabTitle = this.normalizeOptionalPopupTitle(options.popupTabTitle) || (0, import_default_action_popup.resolveFlowSurfaceDefaultActionPopupTabTitle)(actionNode == null ? void 0 : actionNode.use, this.getActionButtonTitle(actionNode));
7303
+ if (!(popupTab == null ? void 0 : popupTab.uid) || !popupTabTitle || this.resolvePopupTabTitle(popupTab) === popupTabTitle) {
7304
+ return;
7305
+ }
7306
+ await this.updatePopupTab(
7307
+ {
7308
+ target: {
7309
+ uid: popupTab.uid
7310
+ },
7311
+ title: popupTabTitle
7312
+ },
6789
7313
  options
6790
7314
  );
6791
- const popupState = await this.resolveDefaultActionPopupSurfaceState(actionNode.uid, options.transaction);
6792
- await this.resetDefaultActionPopupFormLinkageRules(popupState.popupBlock, options);
6793
- await this.syncDefaultActionPopupTabTitle(popupState.actionNode || actionNode, popupState.popupTab, options);
6794
7315
  }
6795
- async applyInlineActionPopup(actionName, actionUid, popup, options) {
7316
+ async syncDefaultActionPopupCopiedTemplateTabTitle(actionUid, fallbackActionNode, options) {
6796
7317
  const actionNode = await this.repository.findModelById(actionUid, {
6797
7318
  transaction: options.transaction,
6798
7319
  includeAsyncNode: true
6799
- });
6800
- if (!(actionNode == null ? void 0 : actionNode.uid)) {
6801
- (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} action '${actionUid}' does not exist`);
6802
- }
7320
+ }) || fallbackActionNode;
6803
7321
  const openView = this.resolvePopupHostOpenView(actionNode);
6804
- if (this.isExternalPopupOpenView(openView, actionNode == null ? void 0 : actionNode.uid)) {
6805
- if (popup == null ? void 0 : popup.saveAsTemplate) {
6806
- (0, import_errors.throwBadRequest)(
6807
- `flowSurfaces ${actionName} popup.saveAsTemplate cannot be combined with external openView.uid`
6808
- );
6809
- }
6810
- if (import_lodash.default.isUndefined(popup) || this.isSemanticallyEmptyInlinePopup(popup)) {
6811
- return;
6812
- }
6813
- (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} popup cannot be combined with external openView.uid`);
7322
+ const copiedPopupHostUid = this.resolveDetachedPopupCopyUid(actionUid, openView);
7323
+ if (!copiedPopupHostUid) {
7324
+ return;
6814
7325
  }
6815
- popup = this.prepareInlinePopupTemplateAliases(actionName, popup, options.popupTemplateAliasSession);
6816
- if (popup && (0, import_default_action_popup.hasFlowSurfaceInlinePopupTemplate)(popup)) {
6817
- await this.configureActionNode(
6818
- {
6819
- uid: actionUid
6820
- },
6821
- actionNode.use,
6822
- {
6823
- openView: this.buildInlinePopupTemplateOpenView(popup)
7326
+ await this.syncDefaultActionPopupTabTitleForHost(actionNode || fallbackActionNode, copiedPopupHostUid, options);
7327
+ }
7328
+ async syncDefaultActionPopupOpenViewTitle(actionUid, fallbackActionNode, options) {
7329
+ const actionNode = await this.repository.findModelById(actionUid, {
7330
+ transaction: options.transaction,
7331
+ includeAsyncNode: true
7332
+ }) || fallbackActionNode;
7333
+ const openViewStep = (0, import_template_service_utils.findFlowTemplateOpenViewStep)(actionNode);
7334
+ const openViewTitle = this.normalizeOptionalPopupTitle(options.openViewTitle) || (0, import_default_action_popup.resolveFlowSurfaceDefaultActionPopupTabTitle)(actionNode == null ? void 0 : actionNode.use, this.getActionButtonTitle(actionNode));
7335
+ if (!openViewStep || !openViewTitle) {
7336
+ return;
7337
+ }
7338
+ const currentOpenView = import_lodash.default.isPlainObject(openViewStep.openView) ? openViewStep.openView : {};
7339
+ if (this.normalizeOptionalPopupTitle(currentOpenView.title) === openViewTitle) {
7340
+ return;
7341
+ }
7342
+ const nextStepParams = import_lodash.default.cloneDeep((actionNode == null ? void 0 : actionNode.stepParams) || {});
7343
+ const currentGroup = import_lodash.default.isPlainObject(nextStepParams[openViewStep.flowKey]) ? import_lodash.default.cloneDeep(nextStepParams[openViewStep.flowKey]) : {};
7344
+ currentGroup[openViewStep.stepKey] = (0, import_service_utils.buildDefinedPayload)({
7345
+ ...currentOpenView,
7346
+ title: openViewTitle
7347
+ });
7348
+ nextStepParams[openViewStep.flowKey] = currentGroup;
7349
+ await this.repository.patch(
7350
+ {
7351
+ uid: actionNode.uid,
7352
+ stepParams: nextStepParams
7353
+ },
7354
+ { transaction: options.transaction }
7355
+ );
7356
+ }
7357
+ async hydrateLocalActionPopupCurrentRecordContext(actionNode, options) {
7358
+ var _a;
7359
+ if (!(actionNode == null ? void 0 : actionNode.uid) || !((_a = options.popupActionContext) == null ? void 0 : _a.hasCurrentRecord)) {
7360
+ return;
7361
+ }
7362
+ const currentOpenView = this.resolvePopupHostOpenView(actionNode);
7363
+ if (this.isExternalPopupOpenView(currentOpenView, actionNode.uid) || (0, import_service_helpers.hasConfiguredFlowContextValue)(currentOpenView == null ? void 0 : currentOpenView.filterByTk)) {
7364
+ return;
7365
+ }
7366
+ const popupProfile = await this.resolvePopupBlockProfile(
7367
+ actionNode.uid,
7368
+ null,
7369
+ actionNode,
7370
+ options.transaction
7371
+ ).catch(() => null);
7372
+ const collectionName = String((currentOpenView == null ? void 0 : currentOpenView.collectionName) || (popupProfile == null ? void 0 : popupProfile.collectionName) || "").trim();
7373
+ if (!collectionName) {
7374
+ return;
7375
+ }
7376
+ const openViewStep = (0, import_template_service_utils.findFlowTemplateOpenViewStep)(actionNode);
7377
+ const flowKey = (openViewStep == null ? void 0 : openViewStep.flowKey) || "popupSettings";
7378
+ const stepKey = (openViewStep == null ? void 0 : openViewStep.stepKey) || "openView";
7379
+ const nextStepParams = import_lodash.default.cloneDeep(actionNode.stepParams || {});
7380
+ const currentGroup = import_lodash.default.isPlainObject(nextStepParams[flowKey]) ? import_lodash.default.cloneDeep(nextStepParams[flowKey]) : {};
7381
+ const currentGroupOpenView = import_lodash.default.isPlainObject(currentGroup[stepKey]) ? currentGroup[stepKey] : {};
7382
+ const nextOpenView = (0, import_service_utils.buildDefinedPayload)({
7383
+ ...currentGroupOpenView,
7384
+ dataSourceKey: (currentOpenView == null ? void 0 : currentOpenView.dataSourceKey) || (popupProfile == null ? void 0 : popupProfile.dataSourceKey) || "main",
7385
+ collectionName,
7386
+ associationName: (currentOpenView == null ? void 0 : currentOpenView.associationName) || (popupProfile == null ? void 0 : popupProfile.associationName),
7387
+ filterByTk: (popupProfile == null ? void 0 : popupProfile.filterByTk) || "{{ctx.view.inputArgs.filterByTk}}",
7388
+ sourceId: (currentOpenView == null ? void 0 : currentOpenView.sourceId) || (popupProfile == null ? void 0 : popupProfile.sourceId)
7389
+ });
7390
+ if (import_lodash.default.isEqual(nextOpenView, currentGroupOpenView)) {
7391
+ return;
7392
+ }
7393
+ currentGroup[stepKey] = nextOpenView;
7394
+ nextStepParams[flowKey] = currentGroup;
7395
+ await this.repository.patch(
7396
+ {
7397
+ uid: actionNode.uid,
7398
+ stepParams: nextStepParams
7399
+ },
7400
+ { transaction: options.transaction }
7401
+ );
7402
+ actionNode.stepParams = nextStepParams;
7403
+ }
7404
+ async applyDefaultActionPopupContent(actionNode, popup, options) {
7405
+ const popupProfile = await this.resolvePopupBlockProfile(actionNode.uid, null, actionNode, options.transaction);
7406
+ if (!(popupProfile == null ? void 0 : popupProfile.isPopupSurface)) {
7407
+ return;
7408
+ }
7409
+ const generatedPopupName = this.resolveGeneratedDefaultActionPopupName(actionNode, popup, popupProfile);
7410
+ await this.compose(
7411
+ this.buildDefaultActionPopupComposeValues(actionNode, popupProfile, popup, options.enabledPackages),
7412
+ options
7413
+ );
7414
+ const popupState = await this.resolveDefaultActionPopupSurfaceState(actionNode.uid, options.transaction);
7415
+ await this.resetDefaultActionPopupFormLinkageRules(popupState.popupBlock, options);
7416
+ await this.syncDefaultActionPopupTabTitle(popupState.actionNode || actionNode, popupState.popupTab, {
7417
+ ...options,
7418
+ popupTabTitle: generatedPopupName || options.popupTabTitle
7419
+ });
7420
+ await this.syncDefaultActionPopupOpenViewTitle(actionNode.uid, popupState.actionNode || actionNode, {
7421
+ ...options,
7422
+ openViewTitle: generatedPopupName || options.popupTabTitle
7423
+ });
7424
+ }
7425
+ async applyInlineActionPopup(actionName, actionUid, popup, options) {
7426
+ const actionNode = await this.repository.findModelById(actionUid, {
7427
+ transaction: options.transaction,
7428
+ includeAsyncNode: true
7429
+ });
7430
+ if (!(actionNode == null ? void 0 : actionNode.uid)) {
7431
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} action '${actionUid}' does not exist`);
7432
+ }
7433
+ const initialOpenView = this.resolvePopupHostOpenView(actionNode);
7434
+ if (import_lodash.default.isUndefined(popup) && options.autoCompleteDefaultPopup === false) {
7435
+ return;
7436
+ }
7437
+ if (this.isExternalPopupOpenView(initialOpenView, actionNode.uid) && (import_lodash.default.isUndefined(popup) || this.isEmptyInlinePopupPayload(popup))) {
7438
+ return;
7439
+ }
7440
+ popup = this.prepareInlinePopupTemplateAliases(actionName, popup, options.popupTemplateAliasSession);
7441
+ popup = this.buildImplicitTemplateDefaultActionPopup(actionNode, popup);
7442
+ const templateOpenViewTitle = this.resolveDefaultActionPopupTemplateOpenViewTitle(actionNode, popup);
7443
+ if (popup && (0, import_default_action_popup.hasFlowSurfaceInlinePopupTemplate)(popup)) {
7444
+ const templateRef = this.normalizeFlowTemplateReference(actionName, popup.template, {
7445
+ expectedType: "popup"
7446
+ });
7447
+ const template = await this.getFlowTemplateOrThrow(actionName, templateRef.uid, {
7448
+ transaction: options.transaction,
7449
+ expectedType: "popup"
7450
+ });
7451
+ await this.configureActionNode(
7452
+ {
7453
+ uid: actionUid
7454
+ },
7455
+ actionNode.use,
7456
+ {
7457
+ openView: this.buildInlinePopupTemplateOpenView(popup, templateOpenViewTitle)
6824
7458
  },
6825
7459
  {
6826
7460
  ...options,
6827
7461
  openViewActionName: actionName
6828
7462
  }
6829
7463
  );
7464
+ if ((0, import_default_action_popup.isFlowSurfaceDefaultActionPopupUse)(actionNode == null ? void 0 : actionNode.use) && templateRef.mode === "copy") {
7465
+ await this.syncDefaultActionPopupCopiedTemplateTabTitle(actionUid, actionNode, {
7466
+ ...options,
7467
+ popupTabTitle: templateOpenViewTitle
7468
+ });
7469
+ }
6830
7470
  return;
6831
7471
  }
6832
7472
  const matchedTemplate = await this.tryResolvePopupTemplateForHost(actionName, popup, actionUid, options);
@@ -6837,21 +7477,37 @@ class FlowSurfacesService {
6837
7477
  },
6838
7478
  actionNode.use,
6839
7479
  {
6840
- openView: this.buildInlinePopupTemplateOpenView({
6841
- ...popup,
6842
- template: {
6843
- uid: matchedTemplate.uid,
6844
- mode: "reference"
6845
- }
6846
- })
7480
+ openView: this.buildInlinePopupTemplateOpenView(
7481
+ {
7482
+ ...popup,
7483
+ template: {
7484
+ uid: matchedTemplate.uid,
7485
+ mode: "reference"
7486
+ }
7487
+ },
7488
+ templateOpenViewTitle
7489
+ )
6847
7490
  },
6848
7491
  {
6849
7492
  ...options,
6850
7493
  openViewActionName: actionName
6851
7494
  }
6852
7495
  );
7496
+ this.registerInlinePopupTemplateAlias(actionName, popup, matchedTemplate, options.popupTemplateAliasSession);
6853
7497
  return;
6854
7498
  }
7499
+ const openView = this.resolvePopupHostOpenView(actionNode);
7500
+ if (this.isExternalPopupOpenView(openView, actionNode == null ? void 0 : actionNode.uid) && !this.isEditableDefaultActionPopupTemplateReference(actionNode, openView)) {
7501
+ if (popup == null ? void 0 : popup.saveAsTemplate) {
7502
+ (0, import_errors.throwBadRequest)(
7503
+ `flowSurfaces ${actionName} popup.saveAsTemplate cannot be combined with external openView.uid`
7504
+ );
7505
+ }
7506
+ if (import_lodash.default.isUndefined(popup) || this.isSemanticallyEmptyInlinePopup(popup)) {
7507
+ return;
7508
+ }
7509
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} popup cannot be combined with external openView.uid`);
7510
+ }
6855
7511
  const shouldAutoCompleteDefaultPopup = this.shouldAutoCompleteDefaultActionPopup(actionNode, popup, options);
6856
7512
  this.assertInlinePopupSaveAsTemplateSource(actionName, popup);
6857
7513
  const hasLocalPopupContent = (0, import_default_action_popup.hasFlowSurfaceInlinePopupBlocks)(popup) || !import_lodash.default.isUndefined(popup == null ? void 0 : popup.layout);
@@ -6863,11 +7519,15 @@ class FlowSurfacesService {
6863
7519
  }
6864
7520
  try {
6865
7521
  if (shouldAutoCompleteDefaultPopup) {
6866
- await this.applyDefaultActionPopupContent(actionNode, popup, options);
7522
+ await this.applyDefaultActionPopupContent(actionNode, popup, {
7523
+ ...options,
7524
+ popupTabTitle: templateOpenViewTitle
7525
+ });
6867
7526
  if (this.shouldAutoSaveDefaultActionPopupTemplate(popup)) {
6868
7527
  await this.autoSaveDefaultActionPopupAsTemplate(actionUid, popup, options);
6869
7528
  }
6870
7529
  } else if (!import_lodash.default.isUndefined(popup)) {
7530
+ await this.hydrateLocalActionPopupCurrentRecordContext(actionNode, options);
6871
7531
  await this.compose(
6872
7532
  {
6873
7533
  target: {
@@ -6894,10 +7554,13 @@ class FlowSurfacesService {
6894
7554
  const writeTarget = this.normalizeWriteTarget("updateSettings", values == null ? void 0 : values.target, values);
6895
7555
  const target = await this.locator.resolve(writeTarget, options);
6896
7556
  const current = await this.loadResolvedNode(target, options.transaction);
7557
+ const normalizedValues = import_lodash.default.cloneDeep(values || {});
7558
+ this.normalizeCanonicalBlockHeaderWriteForUpdateSettings(current, normalizedValues);
6897
7559
  const contract = (0, import_catalog.getNodeContract)(current.use);
6898
7560
  const nextPayload = { uid: current.uid };
7561
+ const shouldStripLegacyBlockHeader = import_lodash.default.has(normalizedValues, ["stepParams", "cardSettings", "titleDescription"]);
6899
7562
  ["props", "decoratorProps", "stepParams", "flowRegistry"].forEach((domain) => {
6900
- if (typeof values[domain] === "undefined") {
7563
+ if (typeof normalizedValues[domain] === "undefined") {
6901
7564
  return;
6902
7565
  }
6903
7566
  if (!contract.editableDomains.includes(domain)) {
@@ -6910,11 +7573,12 @@ class FlowSurfacesService {
6910
7573
  nextPayload[domain] = this.contractGuard.mergeDomainValue(
6911
7574
  domain,
6912
7575
  current[domain],
6913
- values[domain],
7576
+ normalizedValues[domain],
6914
7577
  domainContract,
6915
7578
  current.use
6916
7579
  );
6917
7580
  });
7581
+ this.syncFilterActionSettingsForUpdateSettings(current, normalizedValues, nextPayload);
6918
7582
  this.syncMirroredStepParamsForUpdateSettings(current, nextPayload);
6919
7583
  const popupActionContext = options.popupActionContext || await this.resolveRecordContextPopupActionContextForHost(current, options.transaction);
6920
7584
  await this.normalizeOpenViewForUpdateSettings(
@@ -6929,11 +7593,14 @@ class FlowSurfacesService {
6929
7593
  );
6930
7594
  this.syncChartConfigureForUpdateSettings(current, nextPayload);
6931
7595
  await this.validateChartConfigureForUpdateSettings(current, nextPayload, options.transaction);
7596
+ this.syncCanonicalBlockHeaderForUpdateSettings(current, nextPayload);
7597
+ this.syncMapHeightChromeForUpdateSettings(current, nextPayload);
6932
7598
  this.syncChartCardRuntimeStepParamsForUpdateSettings(
6933
7599
  current,
6934
7600
  nextPayload,
6935
- options.replaceChartCardSettings ? import_lodash.default.get(values, ["stepParams", "cardSettings"]) : void 0
7601
+ options.replaceChartCardSettings ? import_lodash.default.get(normalizedValues, ["stepParams", "cardSettings"]) : void 0
6936
7602
  );
7603
+ this.stripLegacyBlockHeaderChromeForUpdateSettings(current, nextPayload, shouldStripLegacyBlockHeader);
6937
7604
  this.stripLegacyChartCardChromeForUpdateSettings(current, nextPayload);
6938
7605
  const effectiveNode = {
6939
7606
  ...current,
@@ -6943,6 +7610,7 @@ class FlowSurfacesService {
6943
7610
  flowRegistry: nextPayload.flowRegistry ?? current.flowRegistry
6944
7611
  };
6945
7612
  const shouldValidateFlowRegistry = !import_lodash.default.isUndefined(nextPayload.flowRegistry) || !import_lodash.default.isUndefined(nextPayload.stepParams);
7613
+ this.validateCalendarBlockState("updateSettings", effectiveNode);
6946
7614
  if (shouldValidateFlowRegistry && import_lodash.default.isPlainObject(effectiveNode.flowRegistry) && Object.keys(effectiveNode.flowRegistry).length) {
6947
7615
  this.contractGuard.validateFlowRegistry(effectiveNode, effectiveNode.flowRegistry);
6948
7616
  }
@@ -6971,6 +7639,9 @@ class FlowSurfacesService {
6971
7639
  } else if (current.use === "ChartBlockModel" && !import_lodash.default.isUndefined((_b = nextPayload.stepParams) == null ? void 0 : _b.chartSettings)) {
6972
7640
  await this.syncChartDataBindingsForNode(effectiveNode, options.transaction);
6973
7641
  }
7642
+ if (current.use === "CalendarBlockModel") {
7643
+ await this.ensureCalendarBlockPopupHosts(effectiveNode, options.transaction);
7644
+ }
6974
7645
  await this.syncFlowTemplateUsagesForNodeTree(current.uid, options.transaction);
6975
7646
  if (import_approval.APPROVAL_SINGLETON_ACTION_USES.has(current.use || "")) {
6976
7647
  await this.syncApprovalRuntimeConfigForNode(current.uid, options.transaction);
@@ -6980,6 +7651,81 @@ class FlowSurfacesService {
6980
7651
  updated: Object.keys(import_lodash.default.omit(nextPayload, ["uid"]))
6981
7652
  };
6982
7653
  }
7654
+ syncFilterActionSettingsForUpdateSettings(current, values, nextPayload) {
7655
+ if ((current == null ? void 0 : current.use) !== "FilterActionModel") {
7656
+ return;
7657
+ }
7658
+ const hasPropsFilterableFieldNames = import_lodash.default.isPlainObject(values == null ? void 0 : values.props) && Object.prototype.hasOwnProperty.call(values.props, "filterableFieldNames");
7659
+ const hasPropsDefaultFilterValue = import_lodash.default.isPlainObject(values == null ? void 0 : values.props) && Object.prototype.hasOwnProperty.call(values.props, "defaultFilterValue");
7660
+ const hasPropsFilterValue = import_lodash.default.isPlainObject(values == null ? void 0 : values.props) && Object.prototype.hasOwnProperty.call(values.props, "filterValue");
7661
+ const hasStepFilterSettingsClear = import_lodash.default.isPlainObject(values == null ? void 0 : values.stepParams) && Object.prototype.hasOwnProperty.call(values.stepParams, "filterSettings") && (values.stepParams.filterSettings === null || import_lodash.default.isPlainObject(values.stepParams.filterSettings) && !Object.keys(values.stepParams.filterSettings).length);
7662
+ const hasStepFilterableFieldNames = import_lodash.default.has(values, [
7663
+ "stepParams",
7664
+ "filterSettings",
7665
+ "filterableFieldNames",
7666
+ "filterableFieldNames"
7667
+ ]);
7668
+ const hasStepDefaultFilter = import_lodash.default.has(values, ["stepParams", "filterSettings", "defaultFilter", "defaultFilter"]);
7669
+ if (!hasPropsFilterableFieldNames && !hasPropsDefaultFilterValue && !hasPropsFilterValue && !hasStepFilterSettingsClear && !hasStepFilterableFieldNames && !hasStepDefaultFilter) {
7670
+ return;
7671
+ }
7672
+ const nextProps = import_lodash.default.cloneDeep(nextPayload.props ?? (current == null ? void 0 : current.props) ?? {});
7673
+ const nextStepParams = import_lodash.default.cloneDeep(nextPayload.stepParams ?? (current == null ? void 0 : current.stepParams) ?? {});
7674
+ if (hasStepFilterSettingsClear) {
7675
+ if (hasPropsFilterableFieldNames || hasPropsDefaultFilterValue || hasPropsFilterValue) {
7676
+ (0, import_errors.throwBadRequest)(
7677
+ "flowSurfaces updateSettings filter action cannot combine 'stepParams.filterSettings' clear with filter props writes"
7678
+ );
7679
+ }
7680
+ import_lodash.default.unset(nextProps, ["filterableFieldNames"]);
7681
+ import_lodash.default.unset(nextProps, ["defaultFilterValue"]);
7682
+ import_lodash.default.unset(nextProps, ["filterValue"]);
7683
+ import_lodash.default.set(nextStepParams, ["filterSettings"], {});
7684
+ nextPayload.props = nextProps;
7685
+ nextPayload.stepParams = nextStepParams;
7686
+ return;
7687
+ }
7688
+ if (hasPropsFilterableFieldNames || hasStepFilterableFieldNames) {
7689
+ const nextPropNames = import_lodash.default.cloneDeep(import_lodash.default.get(nextProps, ["filterableFieldNames"]));
7690
+ const nextStepNames = import_lodash.default.cloneDeep(
7691
+ import_lodash.default.get(nextStepParams, ["filterSettings", "filterableFieldNames", "filterableFieldNames"])
7692
+ );
7693
+ if (hasPropsFilterableFieldNames && hasStepFilterableFieldNames && !import_lodash.default.isEqual(nextPropNames, nextStepNames)) {
7694
+ (0, import_errors.throwBadRequest)(
7695
+ "flowSurfaces updateSettings filter action values 'props.filterableFieldNames' and 'stepParams.filterSettings.filterableFieldNames.filterableFieldNames' must match"
7696
+ );
7697
+ }
7698
+ const fieldNames = hasStepFilterableFieldNames ? nextStepNames : nextPropNames;
7699
+ nextProps.filterableFieldNames = import_lodash.default.cloneDeep(fieldNames);
7700
+ import_lodash.default.set(
7701
+ nextStepParams,
7702
+ ["filterSettings", "filterableFieldNames", "filterableFieldNames"],
7703
+ import_lodash.default.cloneDeep(fieldNames)
7704
+ );
7705
+ }
7706
+ if (hasPropsDefaultFilterValue || hasPropsFilterValue || hasStepDefaultFilter) {
7707
+ const nextDefaultFilterValue = import_lodash.default.cloneDeep(import_lodash.default.get(nextProps, ["defaultFilterValue"]));
7708
+ const nextFilterValue = import_lodash.default.cloneDeep(import_lodash.default.get(nextProps, ["filterValue"]));
7709
+ const nextStepFilter = import_lodash.default.cloneDeep(import_lodash.default.get(nextStepParams, ["filterSettings", "defaultFilter", "defaultFilter"]));
7710
+ if (hasPropsDefaultFilterValue && hasPropsFilterValue && !import_lodash.default.isEqual(nextDefaultFilterValue, nextFilterValue)) {
7711
+ (0, import_errors.throwBadRequest)(
7712
+ "flowSurfaces updateSettings filter action values 'props.defaultFilterValue' and 'props.filterValue' must match"
7713
+ );
7714
+ }
7715
+ const nextPropFilter = hasPropsDefaultFilterValue ? nextDefaultFilterValue : nextFilterValue;
7716
+ if ((hasPropsDefaultFilterValue || hasPropsFilterValue) && hasStepDefaultFilter && !import_lodash.default.isEqual(nextPropFilter, nextStepFilter)) {
7717
+ (0, import_errors.throwBadRequest)(
7718
+ "flowSurfaces updateSettings filter action values 'props.defaultFilterValue/filterValue' and 'stepParams.filterSettings.defaultFilter.defaultFilter' must match"
7719
+ );
7720
+ }
7721
+ const filterValue = hasStepDefaultFilter ? nextStepFilter : nextPropFilter;
7722
+ nextProps.defaultFilterValue = import_lodash.default.cloneDeep(filterValue);
7723
+ nextProps.filterValue = import_lodash.default.cloneDeep(filterValue);
7724
+ import_lodash.default.set(nextStepParams, ["filterSettings", "defaultFilter", "defaultFilter"], import_lodash.default.cloneDeep(filterValue));
7725
+ }
7726
+ nextPayload.props = nextProps;
7727
+ nextPayload.stepParams = nextStepParams;
7728
+ }
6983
7729
  syncMirroredStepParamsForUpdateSettings(current, nextPayload) {
6984
7730
  const mirrors = UPDATE_SETTINGS_STEP_PARAM_MIRRORS_BY_USE[(current == null ? void 0 : current.use) || ""];
6985
7731
  if (!(mirrors == null ? void 0 : mirrors.length)) {
@@ -7005,6 +7751,106 @@ class FlowSurfacesService {
7005
7751
  nextPayload.stepParams = nextStepParams;
7006
7752
  }
7007
7753
  }
7754
+ normalizeCanonicalBlockHeaderWriteForUpdateSettings(current, values) {
7755
+ const semanticUse = (0, import_approval.normalizeApprovalSemanticUse)(current == null ? void 0 : current.use);
7756
+ if (!CANONICAL_BLOCK_HEADER_USES.has(semanticUse)) {
7757
+ return;
7758
+ }
7759
+ const titleDescriptionPath = ["stepParams", "cardSettings", "titleDescription"];
7760
+ if (!import_lodash.default.has(values, titleDescriptionPath)) {
7761
+ return;
7762
+ }
7763
+ const titleDescription = import_lodash.default.get(values, titleDescriptionPath);
7764
+ if (titleDescription === null || import_lodash.default.isPlainObject(titleDescription) && !Object.keys(titleDescription).length) {
7765
+ import_lodash.default.set(values, titleDescriptionPath, {
7766
+ title: "",
7767
+ description: ""
7768
+ });
7769
+ return;
7770
+ }
7771
+ if (!import_lodash.default.isPlainObject(titleDescription)) {
7772
+ return;
7773
+ }
7774
+ const normalizedTitleDescription = import_lodash.default.cloneDeep(titleDescription);
7775
+ if (Object.prototype.hasOwnProperty.call(titleDescription, "title")) {
7776
+ normalizedTitleDescription.title = (0, import_service_utils.normalizeBlockTitleDescriptionValue)(titleDescription.title);
7777
+ }
7778
+ if (Object.prototype.hasOwnProperty.call(titleDescription, "description")) {
7779
+ normalizedTitleDescription.description = (0, import_service_utils.normalizeBlockTitleDescriptionValue)(titleDescription.description);
7780
+ }
7781
+ import_lodash.default.set(values, titleDescriptionPath, normalizedTitleDescription);
7782
+ }
7783
+ syncCanonicalBlockHeaderForUpdateSettings(current, nextPayload) {
7784
+ const semanticUse = (0, import_approval.normalizeApprovalSemanticUse)(current == null ? void 0 : current.use);
7785
+ if (!CANONICAL_BLOCK_HEADER_USES.has(semanticUse)) {
7786
+ return;
7787
+ }
7788
+ if (import_lodash.default.isUndefined(import_lodash.default.get(nextPayload, ["stepParams", "cardSettings"]))) {
7789
+ return;
7790
+ }
7791
+ const nextStepParams = import_lodash.default.cloneDeep(nextPayload.stepParams ?? (current == null ? void 0 : current.stepParams) ?? {});
7792
+ const nextCardSettings = import_lodash.default.cloneDeep(import_lodash.default.get(nextStepParams, ["cardSettings"]) || {});
7793
+ const normalizedTitleDescription = (0, import_service_utils.normalizeBlockTitleDescription)(import_lodash.default.get(nextCardSettings, ["titleDescription"]));
7794
+ if (normalizedTitleDescription) {
7795
+ import_lodash.default.set(nextCardSettings, ["titleDescription"], normalizedTitleDescription);
7796
+ } else {
7797
+ import_lodash.default.unset(nextCardSettings, ["titleDescription"]);
7798
+ }
7799
+ if (import_lodash.default.isEmpty(nextCardSettings)) {
7800
+ import_lodash.default.unset(nextStepParams, ["cardSettings"]);
7801
+ } else {
7802
+ import_lodash.default.set(nextStepParams, ["cardSettings"], nextCardSettings);
7803
+ }
7804
+ nextPayload.stepParams = nextStepParams;
7805
+ }
7806
+ stripLegacyBlockHeaderChromeForUpdateSettings(current, nextPayload, shouldStrip) {
7807
+ if (!shouldStrip) {
7808
+ return;
7809
+ }
7810
+ const semanticUse = (0, import_approval.normalizeApprovalSemanticUse)(current == null ? void 0 : current.use);
7811
+ if (!CANONICAL_BLOCK_HEADER_USES.has(semanticUse)) {
7812
+ return;
7813
+ }
7814
+ const currentProps = import_lodash.default.isPlainObject(current == null ? void 0 : current.props) ? current.props : {};
7815
+ const currentDecoratorProps = import_lodash.default.isPlainObject(current == null ? void 0 : current.decoratorProps) ? current.decoratorProps : {};
7816
+ const legacyPropKeys = ["title", "displayTitle"];
7817
+ const legacyDecoratorKeys = ["title", "description"];
7818
+ const hasLegacyProps = legacyPropKeys.some((key) => Object.prototype.hasOwnProperty.call(currentProps, key));
7819
+ const hasLegacyDecoratorProps = legacyDecoratorKeys.some(
7820
+ (key) => Object.prototype.hasOwnProperty.call(currentDecoratorProps, key)
7821
+ );
7822
+ if (hasLegacyProps) {
7823
+ nextPayload.props = import_lodash.default.omit(import_lodash.default.cloneDeep(nextPayload.props ?? currentProps), legacyPropKeys);
7824
+ }
7825
+ if (hasLegacyDecoratorProps) {
7826
+ nextPayload.decoratorProps = import_lodash.default.omit(
7827
+ import_lodash.default.cloneDeep(nextPayload.decoratorProps ?? currentDecoratorProps),
7828
+ legacyDecoratorKeys
7829
+ );
7830
+ }
7831
+ }
7832
+ syncMapHeightChromeForUpdateSettings(current, nextPayload) {
7833
+ if ((current == null ? void 0 : current.use) !== "MapBlockModel") {
7834
+ return;
7835
+ }
7836
+ const nextProps = import_lodash.default.isPlainObject(nextPayload.props) ? nextPayload.props : void 0;
7837
+ if (!nextProps) {
7838
+ return;
7839
+ }
7840
+ const nextDecoratorProps = import_lodash.default.cloneDeep(nextPayload.decoratorProps ?? (current == null ? void 0 : current.decoratorProps) ?? {});
7841
+ let changed = false;
7842
+ if (Object.prototype.hasOwnProperty.call(nextProps, "height") && nextDecoratorProps.height !== nextProps.height) {
7843
+ nextDecoratorProps.height = nextProps.height;
7844
+ changed = true;
7845
+ }
7846
+ if (Object.prototype.hasOwnProperty.call(nextProps, "heightMode") && nextDecoratorProps.heightMode !== nextProps.heightMode) {
7847
+ nextDecoratorProps.heightMode = nextProps.heightMode;
7848
+ changed = true;
7849
+ }
7850
+ if (changed) {
7851
+ nextPayload.decoratorProps = (0, import_service_utils.buildDefinedPayload)(nextDecoratorProps);
7852
+ }
7853
+ }
7008
7854
  async normalizeOpenViewForUpdateSettings(actionName, current, nextPayload, options = {}) {
7009
7855
  const openViewPaths = [
7010
7856
  ["popupSettings", "openView"],
@@ -8236,16 +9082,109 @@ class FlowSurfacesService {
8236
9082
  })
8237
9083
  };
8238
9084
  }
9085
+ buildAutoComposeFieldsLayoutRow(fieldKeys, blockType) {
9086
+ const normalizedKeys = fieldKeys.filter(Boolean);
9087
+ if (!normalizedKeys.length) {
9088
+ return [];
9089
+ }
9090
+ if (blockType === "filterForm") {
9091
+ const span = normalizedKeys.length === 1 ? 24 : normalizedKeys.length === 2 ? 12 : 8;
9092
+ return normalizedKeys.map((key) => ({ key, span }));
9093
+ }
9094
+ if (normalizedKeys.length === 1) {
9095
+ return [{ key: normalizedKeys[0], span: 24 }];
9096
+ }
9097
+ return normalizedKeys.map((key) => ({ key, span: 12 }));
9098
+ }
9099
+ buildAutoComposeFieldsLayout(fields, blockType) {
9100
+ if (!COMPOSE_FIELD_GRID_BLOCK_TYPES.has(blockType || "") || !fields.length) {
9101
+ return void 0;
9102
+ }
9103
+ const rows = [];
9104
+ const chunkSize = blockType === "filterForm" ? 3 : 2;
9105
+ let pendingKeys = [];
9106
+ const flushPending = () => {
9107
+ if (!pendingKeys.length) {
9108
+ return;
9109
+ }
9110
+ rows.push(this.buildAutoComposeFieldsLayoutRow(pendingKeys, blockType));
9111
+ pendingKeys = [];
9112
+ };
9113
+ fields.forEach((field) => {
9114
+ const key = String((field == null ? void 0 : field.key) || "").trim();
9115
+ if (!key) {
9116
+ return;
9117
+ }
9118
+ if (String((field == null ? void 0 : field.type) || "").trim() === "divider") {
9119
+ flushPending();
9120
+ rows.push([{ key, span: 24 }]);
9121
+ return;
9122
+ }
9123
+ pendingKeys.push(key);
9124
+ if (pendingKeys.length >= chunkSize) {
9125
+ flushPending();
9126
+ }
9127
+ });
9128
+ flushPending();
9129
+ return rows.length ? { rows } : void 0;
9130
+ }
9131
+ normalizeComposeFieldGroups(input, blockType, context) {
9132
+ if (!COMPOSE_FIELD_GROUP_BLOCK_TYPES.has(blockType)) {
9133
+ (0, import_errors.throwBadRequest)(`${context} fieldGroups is only supported on createForm, editForm or details`);
9134
+ }
9135
+ const fieldGroups = import_lodash.default.castArray(input || []);
9136
+ if (!fieldGroups.length) {
9137
+ (0, import_errors.throwBadRequest)(`${context} fieldGroups must be a non-empty array`);
9138
+ }
9139
+ return fieldGroups.flatMap((group, groupIndex) => {
9140
+ const groupContext = `${context}.fieldGroups[${groupIndex + 1}]`;
9141
+ if (!import_lodash.default.isPlainObject(group)) {
9142
+ (0, import_errors.throwBadRequest)(`${groupContext} must be an object`);
9143
+ }
9144
+ const title = String(group.title || "").trim();
9145
+ if (!title) {
9146
+ (0, import_errors.throwBadRequest)(`${groupContext}.title is required`);
9147
+ }
9148
+ const rawFields = import_lodash.default.castArray(group.fields || []);
9149
+ if (!rawFields.length) {
9150
+ (0, import_errors.throwBadRequest)(`${groupContext}.fields must be a non-empty array`);
9151
+ }
9152
+ const dividerKey = (0, import_service_utils.normalizeFlowSurfaceComposeKey)(
9153
+ String(group.key || title).trim() || `group_${groupIndex + 1}`,
9154
+ `${groupContext}.key`
9155
+ );
9156
+ return [
9157
+ (0, import_service_utils.normalizeComposeFieldSpec)(
9158
+ {
9159
+ key: `${dividerKey}_divider`,
9160
+ type: "divider",
9161
+ settings: {
9162
+ label: title,
9163
+ orientation: "left"
9164
+ }
9165
+ },
9166
+ groupIndex * 1e3
9167
+ ),
9168
+ ...rawFields.map((field, fieldIndex) => (0, import_service_utils.normalizeComposeFieldSpec)(field, groupIndex * 1e3 + fieldIndex + 1))
9169
+ ];
9170
+ });
9171
+ }
8239
9172
  async applyDefaultActionsForCreatedBlock(input, options = {}) {
9173
+ var _a;
8240
9174
  const descriptors = (0, import_default_block_actions.getFlowSurfaceDefaultBlockActions)({
8241
9175
  blockType: input.blockType
8242
9176
  });
8243
9177
  for (const descriptor of descriptors) {
9178
+ let settings = (_a = input.defaultActionSettings) == null ? void 0 : _a[descriptor.type];
9179
+ if (descriptor.type === "filter" && !import_lodash.default.isUndefined(settings)) {
9180
+ settings = this.normalizeDefaultFilterActionSettings("addBlock", settings);
9181
+ }
8244
9182
  const actionValues = (0, import_service_utils.buildDefinedPayload)({
8245
9183
  target: {
8246
9184
  uid: input.blockUid
8247
9185
  },
8248
9186
  type: descriptor.type,
9187
+ settings: !import_lodash.default.isUndefined(settings) ? import_lodash.default.cloneDeep(settings) : void 0,
8249
9188
  popup: descriptor.popup ? import_lodash.default.cloneDeep(descriptor.popup) : void 0
8250
9189
  });
8251
9190
  if (descriptor.scope === "actions") {
@@ -8255,6 +9194,19 @@ class FlowSurfacesService {
8255
9194
  }
8256
9195
  }
8257
9196
  }
9197
+ async resolveReusableSingletonAction(input) {
9198
+ var _a;
9199
+ if (!AUTO_SUBMIT_FORM_BLOCK_USES.has(input.ownerUse || "") || input.actionUse !== "FormSubmitActionModel") {
9200
+ return null;
9201
+ }
9202
+ const parentNode = await this.repository.findModelById(input.parentUid, {
9203
+ transaction: input.transaction,
9204
+ includeAsyncNode: true
9205
+ });
9206
+ return import_lodash.default.castArray(((_a = parentNode == null ? void 0 : parentNode.subModels) == null ? void 0 : _a.actions) || []).find(
9207
+ (action) => (action == null ? void 0 : action.use) === "FormSubmitActionModel" && (action == null ? void 0 : action.uid)
9208
+ ) || null;
9209
+ }
8258
9210
  normalizeComposeBlock(input, index, enabledPackages) {
8259
9211
  if (!import_lodash.default.isPlainObject(input)) {
8260
9212
  (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} must be an object`);
@@ -8295,15 +9247,44 @@ class FlowSurfacesService {
8295
9247
  skipContainerValidation: true
8296
9248
  }
8297
9249
  ) : null;
9250
+ const blockDefaultFilter = (0, import_public_data_surface_default_filter.normalizeFlowSurfacePublicBlockDefaultFilter)("compose", input.defaultFilter, {
9251
+ blockType: type,
9252
+ template,
9253
+ path: `block #${index + 1}`
9254
+ });
8298
9255
  const actions = import_lodash.default.castArray(input.actions || []).map(
8299
9256
  (action, actionIndex) => (0, import_service_utils.normalizeComposeActionSpec)(action, actionIndex)
8300
9257
  );
8301
9258
  const recordActions = import_lodash.default.castArray(input.recordActions || []).map(
8302
9259
  (action, actionIndex) => (0, import_service_utils.normalizeComposeActionSpec)(action, actionIndex)
8303
9260
  );
8304
- const fields = import_lodash.default.castArray(input.fields || []).map(
8305
- (field, fieldIndex) => (0, import_service_utils.normalizeComposeFieldSpec)(field, fieldIndex)
8306
- );
9261
+ const hasFields = Object.prototype.hasOwnProperty.call(input, "fields");
9262
+ const hasFieldGroups = Object.prototype.hasOwnProperty.call(input, "fieldGroups");
9263
+ const hasRecordActions = Object.prototype.hasOwnProperty.call(input, "recordActions");
9264
+ if (type === "calendar") {
9265
+ if (hasFields) {
9266
+ (0, import_errors.throwBadRequest)(
9267
+ `flowSurfaces compose block #${index + 1} calendar does not support fields[] on the main block; add event fields under the quick-create or event-view popup host instead`
9268
+ );
9269
+ }
9270
+ if (hasFieldGroups) {
9271
+ (0, import_errors.throwBadRequest)(
9272
+ `flowSurfaces compose block #${index + 1} calendar does not support fieldGroups[] on the main block; add grouped fields under the quick-create or event-view popup host instead`
9273
+ );
9274
+ }
9275
+ if (hasRecordActions) {
9276
+ (0, import_errors.throwBadRequest)(
9277
+ `flowSurfaces compose block #${index + 1} calendar does not support recordActions[] on the main block; configure event actions inside the event-view popup host instead`
9278
+ );
9279
+ }
9280
+ }
9281
+ if (hasFields && hasFieldGroups) {
9282
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} cannot mix fields with fieldGroups`);
9283
+ }
9284
+ if (hasFieldGroups && Object.prototype.hasOwnProperty.call(input, "fieldsLayout")) {
9285
+ (0, import_errors.throwBadRequest)(`flowSurfaces compose block #${index + 1} cannot mix fieldGroups with fieldsLayout`);
9286
+ }
9287
+ const fields = hasFieldGroups ? this.normalizeComposeFieldGroups(input.fieldGroups, type, `flowSurfaces compose block #${index + 1}`) : import_lodash.default.castArray(input.fields || []).map((field, fieldIndex) => (0, import_service_utils.normalizeComposeFieldSpec)(field, fieldIndex));
8307
9288
  (0, import_service_utils.assertFlowSurfaceComposeUniqueKeys)(fields, `flowSurfaces compose block #${index + 1} fields`);
8308
9289
  (0, import_service_utils.assertFlowSurfaceComposeUniqueKeys)(actions, `flowSurfaces compose block #${index + 1} actions`);
8309
9290
  (0, import_service_utils.assertFlowSurfaceComposeUniqueKeys)(recordActions, `flowSurfaces compose block #${index + 1} recordActions`);
@@ -8327,7 +9308,7 @@ class FlowSurfacesService {
8327
9308
  blockDescriptor,
8328
9309
  blockType: type,
8329
9310
  fields
8330
- });
9311
+ }) || this.buildAutoComposeFieldsLayout(fields, type);
8331
9312
  const mergedActions = (0, import_default_block_actions.mergeFlowSurfaceDefaultBlockActions)({
8332
9313
  blockType: type,
8333
9314
  template,
@@ -8339,6 +9320,10 @@ class FlowSurfacesService {
8339
9320
  `flowSurfaces compose block #${index + 1}`
8340
9321
  )
8341
9322
  });
9323
+ const actionsWithDefaultFilter = (0, import_public_data_surface_default_filter.backfillFlowSurfaceFilterActionDefaultFilter)(
9324
+ mergedActions.actions,
9325
+ blockDefaultFilter
9326
+ );
8342
9327
  return {
8343
9328
  index: index + 1,
8344
9329
  key,
@@ -8348,7 +9333,7 @@ class FlowSurfacesService {
8348
9333
  settings: import_lodash.default.isPlainObject(input.settings) ? input.settings : {},
8349
9334
  fields,
8350
9335
  ...fieldsLayout ? { fieldsLayout } : {},
8351
- actions: mergedActions.actions,
9336
+ actions: actionsWithDefaultFilter,
8352
9337
  recordActions: mergedActions.recordActions,
8353
9338
  template
8354
9339
  };
@@ -8685,19 +9670,17 @@ class FlowSurfacesService {
8685
9670
  }
8686
9671
  async configureTableBlock(target, changes, options) {
8687
9672
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("TableBlockModel");
9673
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
8688
9674
  (0, import_service_utils.assertSupportedSimpleChanges)("table", changes, allowedKeys);
8689
9675
  return this.updateSettings(
8690
9676
  {
8691
9677
  target,
8692
- props: (0, import_service_utils.buildDefinedPayload)({
8693
- title: changes.title,
8694
- displayTitle: changes.displayTitle
8695
- }),
8696
9678
  decoratorProps: (0, import_service_utils.buildDefinedPayload)({
8697
9679
  height: changes.height,
8698
9680
  heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
8699
9681
  }),
8700
9682
  stepParams: {
9683
+ ...cardSettings ? { cardSettings } : {},
8701
9684
  ...changes.resource ? {
8702
9685
  resourceSettings: {
8703
9686
  init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
@@ -8733,11 +9716,108 @@ class FlowSurfacesService {
8733
9716
  options
8734
9717
  );
8735
9718
  }
9719
+ async configureCalendarBlock(target, current, changes, options) {
9720
+ var _a;
9721
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("CalendarBlockModel");
9722
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
9723
+ (0, import_service_utils.assertSupportedSimpleChanges)("calendar", changes, allowedKeys);
9724
+ const currentResourceInit = this.getCalendarBlockResourceInit(current);
9725
+ const nextResourceInit = changes.resource ? (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource) : currentResourceInit;
9726
+ if (nextResourceInit.collectionName && !nextResourceInit.dataSourceKey) {
9727
+ nextResourceInit.dataSourceKey = "main";
9728
+ }
9729
+ const resourceChanged = !!changes.resource;
9730
+ const { collection, collectionName } = this.assertCalendarCollectionCompatible("configure", nextResourceInit);
9731
+ const fieldNames = this.normalizeCalendarFieldNamesForCollection({
9732
+ actionName: "configure",
9733
+ collection,
9734
+ collectionName,
9735
+ currentFieldNames: (_a = current == null ? void 0 : current.props) == null ? void 0 : _a.fieldNames,
9736
+ changes,
9737
+ resetInvalidExisting: resourceChanged
9738
+ });
9739
+ const quickCreatePopupSettings = Object.prototype.hasOwnProperty.call(changes, "quickCreatePopup") ? await this.normalizeCalendarPopupConfigureValue({
9740
+ actionName: "configure calendar quickCreatePopup",
9741
+ blockUid: current.uid,
9742
+ actionKey: "quickCreateAction",
9743
+ value: changes.quickCreatePopup,
9744
+ transaction: options.transaction
9745
+ }) : void 0;
9746
+ const eventPopupSettings = Object.prototype.hasOwnProperty.call(changes, "eventPopup") ? await this.normalizeCalendarPopupConfigureValue({
9747
+ actionName: "configure calendar eventPopup",
9748
+ blockUid: current.uid,
9749
+ actionKey: "eventViewAction",
9750
+ value: changes.eventPopup,
9751
+ transaction: options.transaction
9752
+ }) : void 0;
9753
+ const result = await this.updateSettings(
9754
+ {
9755
+ target,
9756
+ props: (0, import_service_utils.buildDefinedPayload)({
9757
+ fieldNames,
9758
+ defaultView: changes.defaultView,
9759
+ enableQuickCreateEvent: changes.quickCreateEvent,
9760
+ showLunar: changes.showLunar,
9761
+ weekStart: changes.weekStart,
9762
+ quickCreatePopupSettings,
9763
+ eventPopupSettings
9764
+ }),
9765
+ decoratorProps: (0, import_service_utils.buildDefinedPayload)({
9766
+ height: changes.height,
9767
+ heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
9768
+ }),
9769
+ stepParams: {
9770
+ ...cardSettings ? { cardSettings } : {},
9771
+ ...changes.resource ? {
9772
+ resourceSettings: {
9773
+ init: nextResourceInit
9774
+ }
9775
+ } : {},
9776
+ ...(0, import_service_utils.hasDefinedValue)(changes, [
9777
+ "titleField",
9778
+ "colorField",
9779
+ "startField",
9780
+ "endField",
9781
+ "defaultView",
9782
+ "quickCreateEvent",
9783
+ "showLunar",
9784
+ "weekStart",
9785
+ "dataScope",
9786
+ "linkageRules"
9787
+ ]) ? {
9788
+ calendarSettings: (0, import_service_utils.buildDefinedPayload)({
9789
+ ...(0, import_service_utils.hasOwnDefined)(changes, "titleField") ? { titleField: { titleField: fieldNames.title } } : {},
9790
+ ...(0, import_service_utils.hasOwnDefined)(changes, "colorField") ? { colorField: { colorFieldName: fieldNames.colorFieldName || "" } } : {},
9791
+ ...(0, import_service_utils.hasOwnDefined)(changes, "startField") ? { startDateField: { start: fieldNames.start } } : {},
9792
+ ...(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 } } : {},
9797
+ ...(0, import_service_utils.hasOwnDefined)(changes, "dataScope") ? { dataScope: { filter: changes.dataScope } } : {},
9798
+ ...(0, import_service_utils.hasOwnDefined)(changes, "linkageRules") ? { linkageRules: { value: changes.linkageRules } } : {}
9799
+ })
9800
+ } : {}
9801
+ }
9802
+ },
9803
+ options
9804
+ );
9805
+ const reloaded = await this.repository.findModelById(current.uid, {
9806
+ transaction: options.transaction,
9807
+ includeAsyncNode: true
9808
+ });
9809
+ await this.ensureCalendarBlockPopupHosts(reloaded, options.transaction);
9810
+ return result;
9811
+ }
8736
9812
  async configureFormBlock(target, use, changes, options) {
8737
9813
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)(use);
9814
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
8738
9815
  (0, import_service_utils.assertSupportedSimpleChanges)("form", changes, allowedKeys);
8739
9816
  const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
8740
9817
  const nextStepParams = {};
9818
+ if (cardSettings) {
9819
+ nextStepParams.cardSettings = cardSettings;
9820
+ }
8741
9821
  if (changes.resource) {
8742
9822
  nextStepParams.resourceSettings = {
8743
9823
  init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
@@ -8768,8 +9848,6 @@ class FlowSurfacesService {
8768
9848
  {
8769
9849
  target,
8770
9850
  props: (0, import_service_utils.buildDefinedPayload)({
8771
- title: changes.title,
8772
- displayTitle: changes.displayTitle,
8773
9851
  ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
8774
9852
  ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
8775
9853
  }),
@@ -8784,14 +9862,13 @@ class FlowSurfacesService {
8784
9862
  }
8785
9863
  async configureDetailsBlock(target, changes, options) {
8786
9864
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("DetailsBlockModel");
9865
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
8787
9866
  (0, import_service_utils.assertSupportedSimpleChanges)("details", changes, allowedKeys);
8788
9867
  const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
8789
9868
  return this.updateSettings(
8790
9869
  {
8791
9870
  target,
8792
9871
  props: (0, import_service_utils.buildDefinedPayload)({
8793
- title: changes.title,
8794
- displayTitle: changes.displayTitle,
8795
9872
  ...(0, import_service_utils.hasOwnDefined)(changes, "labelWidth") ? { labelWidth: changes.labelWidth } : {},
8796
9873
  ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
8797
9874
  }),
@@ -8800,6 +9877,7 @@ class FlowSurfacesService {
8800
9877
  ...(0, import_service_utils.hasOwnDefined)(changes, "labelWrap") ? { labelWrap: changes.labelWrap } : {}
8801
9878
  }),
8802
9879
  stepParams: {
9880
+ ...cardSettings ? { cardSettings } : {},
8803
9881
  ...changes.resource ? {
8804
9882
  resourceSettings: {
8805
9883
  init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
@@ -8878,20 +9956,18 @@ class FlowSurfacesService {
8878
9956
  }
8879
9957
  async configureListBlock(target, changes, options) {
8880
9958
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("ListBlockModel");
9959
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
8881
9960
  (0, import_service_utils.assertSupportedSimpleChanges)("list", changes, allowedKeys);
8882
9961
  const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
8883
9962
  return this.updateSettings(
8884
9963
  {
8885
9964
  target,
8886
- props: (0, import_service_utils.buildDefinedPayload)({
8887
- title: changes.title,
8888
- displayTitle: changes.displayTitle
8889
- }),
8890
9965
  decoratorProps: (0, import_service_utils.buildDefinedPayload)({
8891
9966
  height: changes.height,
8892
9967
  heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
8893
9968
  }),
8894
9969
  stepParams: {
9970
+ ...cardSettings ? { cardSettings } : {},
8895
9971
  ...changes.resource ? {
8896
9972
  resourceSettings: {
8897
9973
  init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
@@ -8912,21 +9988,19 @@ class FlowSurfacesService {
8912
9988
  }
8913
9989
  async configureGridCardBlock(target, changes, options) {
8914
9990
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("GridCardBlockModel");
9991
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
8915
9992
  (0, import_service_utils.assertSupportedSimpleChanges)("gridCard", changes, allowedKeys);
8916
9993
  const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
8917
9994
  const columns = (0, import_service_utils.normalizeGridCardColumns)(changes.columns);
8918
9995
  return this.updateSettings(
8919
9996
  {
8920
9997
  target,
8921
- props: (0, import_service_utils.buildDefinedPayload)({
8922
- title: changes.title,
8923
- displayTitle: changes.displayTitle
8924
- }),
8925
9998
  decoratorProps: (0, import_service_utils.buildDefinedPayload)({
8926
9999
  height: changes.height,
8927
10000
  heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
8928
10001
  }),
8929
10002
  stepParams: {
10003
+ ...cardSettings ? { cardSettings } : {},
8930
10004
  ...changes.resource ? {
8931
10005
  resourceSettings: {
8932
10006
  init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
@@ -8948,36 +10022,37 @@ class FlowSurfacesService {
8948
10022
  }
8949
10023
  async configureMarkdownBlock(target, changes, options) {
8950
10024
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("MarkdownBlockModel");
10025
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
8951
10026
  (0, import_service_utils.assertSupportedSimpleChanges)("markdown", changes, allowedKeys);
8952
10027
  return this.updateSettings(
8953
10028
  {
8954
10029
  target,
8955
10030
  props: (0, import_service_utils.buildDefinedPayload)({
8956
- title: changes.title,
8957
- displayTitle: changes.displayTitle,
8958
10031
  content: changes.content,
8959
10032
  value: changes.content
8960
10033
  }),
8961
- stepParams: (0, import_service_utils.hasOwnDefined)(changes, "content") ? {
8962
- markdownBlockSettings: {
8963
- editMarkdown: {
8964
- content: changes.content
10034
+ stepParams: (0, import_service_utils.buildDefinedPayload)({
10035
+ ...cardSettings ? { cardSettings } : {},
10036
+ ...(0, import_service_utils.hasOwnDefined)(changes, "content") ? {
10037
+ markdownBlockSettings: {
10038
+ editMarkdown: {
10039
+ content: changes.content
10040
+ }
8965
10041
  }
8966
- }
8967
- } : void 0
10042
+ } : {}
10043
+ })
8968
10044
  },
8969
10045
  options
8970
10046
  );
8971
10047
  }
8972
10048
  async configureIframeBlock(target, changes, options) {
8973
10049
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("IframeBlockModel");
10050
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
8974
10051
  (0, import_service_utils.assertSupportedSimpleChanges)("iframe", changes, allowedKeys);
8975
10052
  return this.updateSettings(
8976
10053
  {
8977
10054
  target,
8978
10055
  props: (0, import_service_utils.buildDefinedPayload)({
8979
- title: changes.title,
8980
- displayTitle: changes.displayTitle,
8981
10056
  height: changes.height,
8982
10057
  heightMode: changes.heightMode,
8983
10058
  mode: changes.mode,
@@ -8987,19 +10062,22 @@ class FlowSurfacesService {
8987
10062
  allow: changes.allow,
8988
10063
  htmlId: changes.htmlId
8989
10064
  }),
8990
- stepParams: (0, import_service_utils.hasDefinedValue)(changes, ["height", "mode", "url", "html", "params", "allow", "htmlId"]) ? {
8991
- iframeBlockSettings: {
8992
- editIframe: (0, import_service_utils.buildDefinedPayload)({
8993
- height: changes.height,
8994
- mode: changes.mode,
8995
- url: changes.url,
8996
- html: changes.html,
8997
- params: changes.params,
8998
- allow: changes.allow,
8999
- htmlId: changes.htmlId
9000
- })
9001
- }
9002
- } : void 0
10065
+ stepParams: (0, import_service_utils.buildDefinedPayload)({
10066
+ ...cardSettings ? { cardSettings } : {},
10067
+ ...(0, import_service_utils.hasDefinedValue)(changes, ["height", "mode", "url", "html", "params", "allow", "htmlId"]) ? {
10068
+ iframeBlockSettings: {
10069
+ editIframe: (0, import_service_utils.buildDefinedPayload)({
10070
+ height: changes.height,
10071
+ mode: changes.mode,
10072
+ url: changes.url,
10073
+ html: changes.html,
10074
+ params: changes.params,
10075
+ allow: changes.allow,
10076
+ htmlId: changes.htmlId
10077
+ })
10078
+ }
10079
+ } : {}
10080
+ })
9003
10081
  },
9004
10082
  options
9005
10083
  );
@@ -9007,7 +10085,7 @@ class FlowSurfacesService {
9007
10085
  async configureChartBlock(target, changes, options) {
9008
10086
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("ChartBlockModel");
9009
10087
  (0, import_service_utils.assertSupportedSimpleChanges)("chart", changes, allowedKeys);
9010
- const shouldUpdateCardSettings = ["title", "displayTitle", "height", "heightMode"].some(
10088
+ const shouldUpdateCardSettings = ["title", "description", "height", "heightMode"].some(
9011
10089
  (key) => Object.prototype.hasOwnProperty.call(changes, key)
9012
10090
  );
9013
10091
  const shouldUpdateConfigure = ["configure", "query", "visual", "events"].some(
@@ -9064,23 +10142,86 @@ class FlowSurfacesService {
9064
10142
  }
9065
10143
  async configureActionPanelBlock(target, changes, options) {
9066
10144
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("ActionPanelBlockModel");
10145
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
9067
10146
  (0, import_service_utils.assertSupportedSimpleChanges)("actionPanel", changes, allowedKeys);
9068
10147
  const layoutValue = (0, import_service_utils.normalizeSimpleLayoutValue)(changes.layout);
9069
10148
  return this.updateSettings(
9070
10149
  {
9071
10150
  target,
9072
10151
  props: (0, import_service_utils.buildDefinedPayload)({
9073
- title: changes.title,
9074
- displayTitle: changes.displayTitle,
9075
10152
  layout: layoutValue,
9076
10153
  ellipsis: changes.ellipsis
9077
10154
  }),
9078
- stepParams: (0, import_service_utils.hasDefinedValue)(changes, ["layout", "ellipsis"]) ? {
9079
- actionPanelBlockSetting: (0, import_service_utils.buildDefinedPayload)({
9080
- ...(0, import_service_utils.hasOwnDefined)(changes, "layout") ? { layout: { layout: layoutValue } } : {},
9081
- ...(0, import_service_utils.hasOwnDefined)(changes, "ellipsis") ? { ellipsis: { ellipsis: changes.ellipsis } } : {}
9082
- })
9083
- } : void 0
10155
+ stepParams: (0, import_service_utils.buildDefinedPayload)({
10156
+ ...cardSettings ? { cardSettings } : {},
10157
+ ...(0, import_service_utils.hasDefinedValue)(changes, ["layout", "ellipsis"]) ? {
10158
+ actionPanelBlockSetting: (0, import_service_utils.buildDefinedPayload)({
10159
+ ...(0, import_service_utils.hasOwnDefined)(changes, "layout") ? { layout: { layout: layoutValue } } : {},
10160
+ ...(0, import_service_utils.hasOwnDefined)(changes, "ellipsis") ? { ellipsis: { ellipsis: changes.ellipsis } } : {}
10161
+ })
10162
+ } : {}
10163
+ })
10164
+ },
10165
+ options
10166
+ );
10167
+ }
10168
+ async configureMapBlock(target, changes, options) {
10169
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("MapBlockModel");
10170
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10171
+ (0, import_service_utils.assertSupportedSimpleChanges)("map", changes, allowedKeys);
10172
+ return this.updateSettings(
10173
+ {
10174
+ target,
10175
+ decoratorProps: (0, import_service_utils.buildDefinedPayload)({
10176
+ height: changes.height,
10177
+ heightMode: (0, import_service_utils.normalizePublicBlockHeightMode)(changes.heightMode)
10178
+ }),
10179
+ stepParams: (0, import_service_utils.buildDefinedPayload)({
10180
+ ...cardSettings ? { cardSettings } : {},
10181
+ ...changes.resource ? {
10182
+ resourceSettings: {
10183
+ init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
10184
+ }
10185
+ } : {},
10186
+ ...(0, import_service_utils.hasDefinedValue)(changes, ["mapField", "marker", "dataScope", "sorting", "zoom"]) ? {
10187
+ createMapBlock: (0, import_service_utils.buildDefinedPayload)({
10188
+ ...(0, import_service_utils.hasOwnDefined)(changes, "mapField") || (0, import_service_utils.hasOwnDefined)(changes, "marker") ? {
10189
+ init: (0, import_service_utils.buildDefinedPayload)({
10190
+ mapField: changes.mapField,
10191
+ marker: changes.marker
10192
+ })
10193
+ } : {},
10194
+ ...(0, import_service_utils.hasOwnDefined)(changes, "dataScope") ? { dataScope: { filter: changes.dataScope } } : {},
10195
+ ...(0, import_service_utils.hasOwnDefined)(changes, "sorting") ? { lineSort: { sort: changes.sorting } } : {},
10196
+ ...(0, import_service_utils.hasOwnDefined)(changes, "zoom") ? { mapZoom: { zoom: changes.zoom } } : {}
10197
+ })
10198
+ } : {}
10199
+ })
10200
+ },
10201
+ options
10202
+ );
10203
+ }
10204
+ async configureCommentsBlock(target, changes, options) {
10205
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("CommentsBlockModel");
10206
+ const cardSettings = (0, import_service_utils.buildBlockTitleDescriptionFromSemanticChanges)(changes);
10207
+ (0, import_service_utils.assertSupportedSimpleChanges)("comments", changes, allowedKeys);
10208
+ return this.updateSettings(
10209
+ {
10210
+ target,
10211
+ stepParams: (0, import_service_utils.buildDefinedPayload)({
10212
+ ...cardSettings ? { cardSettings } : {},
10213
+ ...changes.resource ? {
10214
+ resourceSettings: {
10215
+ init: (0, import_service_utils.normalizeSimpleResourceInit)(changes.resource)
10216
+ }
10217
+ } : {},
10218
+ ...(0, import_service_utils.hasDefinedValue)(changes, ["pageSize", "dataScope"]) ? {
10219
+ commentsSettings: (0, import_service_utils.buildDefinedPayload)({
10220
+ ...(0, import_service_utils.hasOwnDefined)(changes, "pageSize") ? { pageSize: { pageSize: changes.pageSize } } : {},
10221
+ ...(0, import_service_utils.hasOwnDefined)(changes, "dataScope") ? { dataScope: { filter: changes.dataScope } } : {}
10222
+ })
10223
+ } : {}
10224
+ })
9084
10225
  },
9085
10226
  options
9086
10227
  );
@@ -9192,6 +10333,29 @@ class FlowSurfacesService {
9192
10333
  options
9193
10334
  );
9194
10335
  }
10336
+ async configureDividerItem(target, changes, options) {
10337
+ const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)("DividerItemModel");
10338
+ (0, import_service_utils.assertSupportedSimpleChanges)("divider", changes, allowedKeys);
10339
+ const dividerSettings = (0, import_service_utils.buildDefinedPayload)({
10340
+ label: changes.label,
10341
+ orientation: changes.orientation,
10342
+ dashed: changes.dashed,
10343
+ color: changes.color,
10344
+ borderColor: changes.borderColor
10345
+ });
10346
+ return this.updateSettings(
10347
+ {
10348
+ target,
10349
+ props: dividerSettings,
10350
+ stepParams: Object.keys(dividerSettings).length ? {
10351
+ markdownItemSetting: {
10352
+ title: dividerSettings
10353
+ }
10354
+ } : void 0
10355
+ },
10356
+ options
10357
+ );
10358
+ }
9195
10359
  async configureFieldWrapper(target, current, changes, options) {
9196
10360
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
9197
10361
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
@@ -9518,9 +10682,19 @@ class FlowSurfacesService {
9518
10682
  }
9519
10683
  return result;
9520
10684
  }
10685
+ normalizeFilterActionDefaultFilterValue(value) {
10686
+ if (value === null || import_lodash.default.isPlainObject(value) && !Object.keys(value).length) {
10687
+ return {
10688
+ logic: "$and",
10689
+ items: []
10690
+ };
10691
+ }
10692
+ return import_lodash.default.cloneDeep(value);
10693
+ }
9521
10694
  async configureActionNode(target, use, changes, options) {
9522
10695
  const allowedKeys = (0, import_configure_options.getConfigureOptionKeysForUse)(use);
9523
10696
  (0, import_service_utils.assertSupportedSimpleChanges)("action", changes, allowedKeys);
10697
+ const normalizedDefaultFilter = (0, import_service_utils.hasOwnDefined)(changes, "defaultFilter") ? this.normalizeFilterActionDefaultFilterValue(changes.defaultFilter) : void 0;
9524
10698
  const stepParams = {};
9525
10699
  if ((0, import_service_utils.hasDefinedValue)(changes, ["title", "tooltip", "icon", "type", "danger", "color", "linkageRules"])) {
9526
10700
  stepParams.buttonSettings = {
@@ -9537,6 +10711,23 @@ class FlowSurfacesService {
9537
10711
  ...(0, import_service_utils.hasOwnDefined)(changes, "linkageRules") ? { linkageRules: changes.linkageRules } : {}
9538
10712
  };
9539
10713
  }
10714
+ if ((0, import_service_utils.hasOwnDefined)(changes, "filterableFieldNames") || (0, import_service_utils.hasOwnDefined)(changes, "defaultFilter")) {
10715
+ if (use !== "FilterActionModel") {
10716
+ (0, import_errors.throwBadRequest)(`flowSurfaces configure action '${use}' does not support filterableFieldNames/defaultFilter`);
10717
+ }
10718
+ stepParams.filterSettings = (0, import_service_utils.buildDefinedPayload)({
10719
+ ...(0, import_service_utils.hasOwnDefined)(changes, "filterableFieldNames") ? {
10720
+ filterableFieldNames: {
10721
+ filterableFieldNames: import_lodash.default.cloneDeep(changes.filterableFieldNames)
10722
+ }
10723
+ } : {},
10724
+ ...(0, import_service_utils.hasOwnDefined)(changes, "defaultFilter") ? {
10725
+ defaultFilter: {
10726
+ defaultFilter: normalizedDefaultFilter
10727
+ }
10728
+ } : {}
10729
+ });
10730
+ }
9540
10731
  if ((0, import_service_utils.hasOwnDefined)(changes, "approvalReturn")) {
9541
10732
  if (use !== "ProcessFormReturnModel") {
9542
10733
  (0, import_errors.throwBadRequest)(`flowSurfaces configure action '${use}' does not support approvalReturn`);
@@ -9707,7 +10898,12 @@ class FlowSurfacesService {
9707
10898
  htmlType: changes.htmlType,
9708
10899
  position: changes.position,
9709
10900
  danger: changes.danger,
9710
- color: changes.color
10901
+ color: changes.color,
10902
+ ...(0, import_service_utils.hasOwnDefined)(changes, "filterableFieldNames") ? { filterableFieldNames: import_lodash.default.cloneDeep(changes.filterableFieldNames) } : {},
10903
+ ...(0, import_service_utils.hasOwnDefined)(changes, "defaultFilter") ? {
10904
+ defaultFilterValue: normalizedDefaultFilter,
10905
+ filterValue: import_lodash.default.cloneDeep(normalizedDefaultFilter)
10906
+ } : {}
9711
10907
  }),
9712
10908
  stepParams: Object.keys(stepParams).length ? stepParams : void 0
9713
10909
  },
@@ -10673,6 +11869,441 @@ class FlowSurfacesService {
10673
11869
  const dataSource = (_a = dataSourceManager == null ? void 0 : dataSourceManager.get) == null ? void 0 : _a.call(dataSourceManager, normalizedDataSourceKey);
10674
11870
  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));
10675
11871
  }
11872
+ normalizeCalendarFieldPathInput(value, context, options = {}) {
11873
+ if (import_lodash.default.isUndefined(value)) {
11874
+ return void 0;
11875
+ }
11876
+ if (import_lodash.default.isNull(value) || value === "") {
11877
+ if (options.allowEmpty) {
11878
+ return "";
11879
+ }
11880
+ (0, import_errors.throwBadRequest)(`${context} is required`);
11881
+ }
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`);
11885
+ }
11886
+ return normalized;
11887
+ }
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
11896
+ ].filter(Boolean);
11897
+ return candidates.some((item) => supportedTypes.has(String(item)));
11898
+ }
11899
+ isCalendarTitleField(field) {
11900
+ return new Set(this.getCalendarTitleFieldInterfaces()).has(String((0, import_service_helpers.getFieldInterface)(field) || ""));
11901
+ }
11902
+ isCalendarColorField(field) {
11903
+ return new Set(this.getCalendarColorFieldInterfaces()).has(String((0, import_service_helpers.getFieldInterface)(field) || ""));
11904
+ }
11905
+ getCalendarPluginFieldCapabilities(input) {
11906
+ const calendarPlugin = this.plugin.app.pm.get("calendar");
11907
+ const source = typeof (calendarPlugin == null ? void 0 : calendarPlugin[input.getter]) === "function" ? calendarPlugin[input.getter]() : calendarPlugin == null ? void 0 : calendarPlugin[input.property];
11908
+ return normalizeCalendarFieldCapabilityValues(source, input.defaults);
11909
+ }
11910
+ getCalendarTitleFieldInterfaces() {
11911
+ const defaults = this.plugin.app.pm.get("field-sequence") ? [...DEFAULT_CALENDAR_TITLE_FIELD_INTERFACES, "sequence"] : DEFAULT_CALENDAR_TITLE_FIELD_INTERFACES;
11912
+ return this.getCalendarPluginFieldCapabilities({
11913
+ getter: "getTitleFieldInterfaces",
11914
+ property: "titleFieldInterfaces",
11915
+ defaults
11916
+ });
11917
+ }
11918
+ getCalendarColorFieldInterfaces() {
11919
+ return this.getCalendarPluginFieldCapabilities({
11920
+ getter: "getColorFieldInterfaces",
11921
+ property: "colorFieldInterfaces",
11922
+ defaults: DEFAULT_CALENDAR_COLOR_FIELD_INTERFACES
11923
+ });
11924
+ }
11925
+ getCalendarDateFieldTypes() {
11926
+ return this.getCalendarPluginFieldCapabilities({
11927
+ getter: "getDateTimeFieldInterfaces",
11928
+ property: "dateTimeFieldInterfaces",
11929
+ defaults: DEFAULT_CALENDAR_DATE_TIME_FIELD_TYPES
11930
+ });
11931
+ }
11932
+ getCalendarTitleFallbackFieldName(collection) {
11933
+ var _a;
11934
+ const filterTargetKey = (collection == null ? void 0 : collection.filterTargetKey) || ((_a = collection == null ? void 0 : collection.options) == null ? void 0 : _a.filterTargetKey);
11935
+ if (Array.isArray(filterTargetKey)) {
11936
+ return filterTargetKey[0] || "id";
11937
+ }
11938
+ return filterTargetKey || "id";
11939
+ }
11940
+ isCalendarTitleFallbackField(collection, fieldPath) {
11941
+ const normalized = String(fieldPath || "").trim();
11942
+ return normalized === "id" || normalized === this.getCalendarTitleFallbackFieldName(collection);
11943
+ }
11944
+ getCalendarDateFields(collection) {
11945
+ return (0, import_service_helpers.getCollectionFields)(collection).filter((field) => this.isCalendarDateField(field));
11946
+ }
11947
+ resolveCalendarDefaultFieldNames(collection) {
11948
+ const titleField = (0, import_service_helpers.getCollectionFields)(collection).filter((field) => this.isCalendarTitleField(field)).map((field) => (0, import_service_helpers.getFieldName)(field)).find(Boolean) || this.getCalendarTitleFallbackFieldName(collection);
11949
+ const dateFields = this.getCalendarDateFields(collection).map((field) => (0, import_service_helpers.getFieldName)(field)).filter(Boolean);
11950
+ const startField = dateFields.find((fieldName) => fieldName === "createdAt") || dateFields[0];
11951
+ const endField = dateFields.find((fieldName) => fieldName !== startField);
11952
+ return (0, import_service_utils.buildDefinedPayload)({
11953
+ id: "id",
11954
+ title: titleField,
11955
+ start: startField,
11956
+ end: endField
11957
+ });
11958
+ }
11959
+ getCalendarCollectionOrThrow(actionName, resourceInit) {
11960
+ const dataSourceKey = String((resourceInit == null ? void 0 : resourceInit.dataSourceKey) || "main").trim() || "main";
11961
+ const collectionName = String((resourceInit == null ? void 0 : resourceInit.collectionName) || "").trim();
11962
+ if (!collectionName) {
11963
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} calendar block requires resource.collectionName`);
11964
+ }
11965
+ const collection = this.getCollection(dataSourceKey, collectionName);
11966
+ if (!collection) {
11967
+ (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} calendar collection '${dataSourceKey}.${collectionName}' not found`);
11968
+ }
11969
+ return {
11970
+ dataSourceKey,
11971
+ collectionName,
11972
+ collection
11973
+ };
11974
+ }
11975
+ assertCalendarCollectionCompatible(actionName, resourceInit) {
11976
+ const resolved = this.getCalendarCollectionOrThrow(actionName, resourceInit);
11977
+ if (!this.getCalendarDateFields(resolved.collection).length) {
11978
+ (0, import_errors.throwBadRequest)(
11979
+ `flowSurfaces ${actionName} calendar collection '${resolved.dataSourceKey}.${resolved.collectionName}' must contain at least one date field`
11980
+ );
11981
+ }
11982
+ return resolved;
11983
+ }
11984
+ assertCalendarFieldBinding(input) {
11985
+ const field = (0, import_service_helpers.resolveFieldFromCollection)(input.collection, input.fieldPath);
11986
+ if (input.kind === "titleField" && !field && this.isCalendarTitleFallbackField(input.collection, input.fieldPath)) {
11987
+ return;
11988
+ }
11989
+ if (!field) {
11990
+ (0, import_errors.throwBadRequest)(
11991
+ `flowSurfaces ${input.actionName} calendar ${input.kind} '${input.fieldPath}' does not exist in collection '${input.collectionName}'`
11992
+ );
11993
+ }
11994
+ const supported = input.kind === "titleField" ? this.isCalendarTitleField(field) || this.isCalendarTitleFallbackField(input.collection, input.fieldPath) : input.kind === "colorField" ? this.isCalendarColorField(field) : this.isCalendarDateField(field);
11995
+ if (!supported) {
11996
+ (0, import_errors.throwBadRequest)(
11997
+ `flowSurfaces ${input.actionName} calendar ${input.kind} '${input.fieldPath}' is not supported by CalendarBlockModel`
11998
+ );
11999
+ }
12000
+ }
12001
+ normalizeCalendarFieldNamesForCollection(input) {
12002
+ const defaults = this.resolveCalendarDefaultFieldNames(input.collection);
12003
+ const current = import_lodash.default.cloneDeep(input.currentFieldNames || {});
12004
+ const nextFieldNames = {
12005
+ id: current.id || "id",
12006
+ title: current.title || defaults.title,
12007
+ start: current.start || defaults.start,
12008
+ end: current.end || defaults.end,
12009
+ colorFieldName: current.colorFieldName
12010
+ };
12011
+ const isExistingValid = (kind, fieldPath) => {
12012
+ const normalized = this.normalizeCalendarFieldPathInput(fieldPath, `${input.actionName} ${kind}`, {
12013
+ allowEmpty: kind === "colorField" || kind === "endField"
12014
+ });
12015
+ if (!normalized) {
12016
+ return kind === "colorField" || kind === "endField";
12017
+ }
12018
+ try {
12019
+ this.assertCalendarFieldBinding({
12020
+ actionName: input.actionName,
12021
+ collection: input.collection,
12022
+ collectionName: input.collectionName,
12023
+ fieldPath: normalized,
12024
+ kind
12025
+ });
12026
+ return true;
12027
+ } catch (error) {
12028
+ return false;
12029
+ }
12030
+ };
12031
+ if (input.resetInvalidExisting) {
12032
+ if (!isExistingValid("titleField", nextFieldNames.title)) {
12033
+ nextFieldNames.title = defaults.title;
12034
+ }
12035
+ if (!isExistingValid("startField", nextFieldNames.start)) {
12036
+ nextFieldNames.start = defaults.start;
12037
+ }
12038
+ if (!isExistingValid("endField", nextFieldNames.end)) {
12039
+ nextFieldNames.end = defaults.end;
12040
+ }
12041
+ if (nextFieldNames.colorFieldName && !isExistingValid("colorField", nextFieldNames.colorFieldName)) {
12042
+ nextFieldNames.colorFieldName = null;
12043
+ }
12044
+ }
12045
+ const applyExplicitField = (changeKey, storageKey, allowEmpty = false) => {
12046
+ if (!input.changes || !Object.prototype.hasOwnProperty.call(input.changes, changeKey)) {
12047
+ return;
12048
+ }
12049
+ const normalized = this.normalizeCalendarFieldPathInput(
12050
+ input.changes[changeKey],
12051
+ `flowSurfaces ${input.actionName} calendar ${changeKey}`,
12052
+ { allowEmpty }
12053
+ );
12054
+ if (!normalized) {
12055
+ nextFieldNames[storageKey] = null;
12056
+ return;
12057
+ }
12058
+ this.assertCalendarFieldBinding({
12059
+ actionName: input.actionName,
12060
+ collection: input.collection,
12061
+ collectionName: input.collectionName,
12062
+ fieldPath: normalized,
12063
+ kind: changeKey
12064
+ });
12065
+ nextFieldNames[storageKey] = normalized;
12066
+ };
12067
+ applyExplicitField("titleField", "title");
12068
+ applyExplicitField("startField", "start");
12069
+ applyExplicitField("endField", "end", true);
12070
+ applyExplicitField("colorField", "colorFieldName", true);
12071
+ if (!nextFieldNames.title) {
12072
+ nextFieldNames.title = defaults.title;
12073
+ }
12074
+ if (!nextFieldNames.start) {
12075
+ nextFieldNames.start = defaults.start;
12076
+ }
12077
+ return (0, import_service_utils.buildDefinedPayload)({
12078
+ id: nextFieldNames.id || "id",
12079
+ title: nextFieldNames.title,
12080
+ start: nextFieldNames.start,
12081
+ end: nextFieldNames.end,
12082
+ colorFieldName: nextFieldNames.colorFieldName
12083
+ });
12084
+ }
12085
+ normalizeCalendarPopupSettings(actionKey, popupSettings) {
12086
+ const nextParams = import_lodash.default.cloneDeep(popupSettings || {});
12087
+ const popupTemplateUidProvided = Object.prototype.hasOwnProperty.call(nextParams, "popupTemplateUid");
12088
+ const popupTemplateUid = typeof nextParams.popupTemplateUid === "string" ? nextParams.popupTemplateUid.trim() : nextParams.popupTemplateUid;
12089
+ if (popupTemplateUidProvided && (popupTemplateUid === void 0 || popupTemplateUid === null || popupTemplateUid === "")) {
12090
+ delete nextParams.popupTemplateUid;
12091
+ delete nextParams.popupTemplateContext;
12092
+ delete nextParams.popupTemplateHasFilterByTk;
12093
+ delete nextParams.popupTemplateHasSourceId;
12094
+ delete nextParams.uid;
12095
+ }
12096
+ if (actionKey === "quickCreateAction") {
12097
+ if (nextParams.popupTemplateHasFilterByTk) {
12098
+ delete nextParams.popupTemplateUid;
12099
+ delete nextParams.popupTemplateContext;
12100
+ delete nextParams.popupTemplateHasFilterByTk;
12101
+ delete nextParams.popupTemplateHasSourceId;
12102
+ delete nextParams.uid;
12103
+ }
12104
+ delete nextParams.filterByTk;
12105
+ }
12106
+ return nextParams;
12107
+ }
12108
+ getCalendarPopupActionUse(actionKey) {
12109
+ return actionKey === "quickCreateAction" ? "CalendarQuickCreateActionModel" : "CalendarEventViewActionModel";
12110
+ }
12111
+ getCalendarPopupPropKey(actionKey) {
12112
+ return actionKey === "quickCreateAction" ? "quickCreatePopupSettings" : "eventPopupSettings";
12113
+ }
12114
+ getCalendarPopupActionUid(calendarUid, actionKey) {
12115
+ return `${calendarUid}-${actionKey}`;
12116
+ }
12117
+ getCalendarBlockResourceInit(blockNode) {
12118
+ const resourceInit = import_lodash.default.cloneDeep(import_lodash.default.get(blockNode, ["stepParams", "resourceSettings", "init"]) || {});
12119
+ if (resourceInit.collectionName && !resourceInit.dataSourceKey) {
12120
+ resourceInit.dataSourceKey = "main";
12121
+ }
12122
+ return resourceInit;
12123
+ }
12124
+ buildCalendarPopupOpenView(input) {
12125
+ const actionUid = this.getCalendarPopupActionUid(input.blockNode.uid, input.actionKey);
12126
+ const resourceInit = input.resourceInit || this.getCalendarBlockResourceInit(input.blockNode);
12127
+ const defaults = (0, import_service_utils.buildDefinedPayload)({
12128
+ mode: "drawer",
12129
+ size: "medium",
12130
+ pageModelClass: "ChildPageModel",
12131
+ uid: actionUid,
12132
+ collectionName: resourceInit.collectionName,
12133
+ dataSourceKey: resourceInit.dataSourceKey || (resourceInit.collectionName ? "main" : void 0)
12134
+ });
12135
+ const current = this.normalizeCalendarPopupSettings(
12136
+ input.actionKey,
12137
+ import_lodash.default.get(input.blockNode, ["props", this.getCalendarPopupPropKey(input.actionKey)]) || {}
12138
+ );
12139
+ return (0, import_service_utils.buildDefinedPayload)({
12140
+ ...defaults,
12141
+ ...current,
12142
+ uid: current.uid || defaults.uid,
12143
+ collectionName: current.collectionName || defaults.collectionName,
12144
+ dataSourceKey: current.dataSourceKey || defaults.dataSourceKey
12145
+ });
12146
+ }
12147
+ async normalizeCalendarPopupConfigureValue(input) {
12148
+ if (import_lodash.default.isUndefined(input.value)) {
12149
+ return void 0;
12150
+ }
12151
+ if (import_lodash.default.isNull(input.value)) {
12152
+ return {};
12153
+ }
12154
+ const actionUid = this.getCalendarPopupActionUid(input.blockUid, input.actionKey);
12155
+ const normalized = await this.normalizeOpenView(input.actionName, input.value, {
12156
+ transaction: input.transaction,
12157
+ popupTemplateHostUid: actionUid,
12158
+ popupActionContext: {
12159
+ hasCurrentRecord: input.actionKey === "eventViewAction"
12160
+ }
12161
+ });
12162
+ return this.normalizeCalendarPopupSettings(input.actionKey, normalized || {});
12163
+ }
12164
+ buildCalendarInitialBlockProps(input) {
12165
+ const { collection, collectionName } = this.assertCalendarCollectionCompatible(
12166
+ input.actionName,
12167
+ input.resourceInit
12168
+ );
12169
+ const currentProps = import_lodash.default.cloneDeep(input.props || {});
12170
+ return {
12171
+ ...currentProps,
12172
+ fieldNames: this.normalizeCalendarFieldNamesForCollection({
12173
+ actionName: input.actionName,
12174
+ collection,
12175
+ collectionName,
12176
+ currentFieldNames: currentProps.fieldNames,
12177
+ resetInvalidExisting: true
12178
+ }),
12179
+ defaultView: currentProps.defaultView || "month",
12180
+ enableQuickCreateEvent: typeof currentProps.enableQuickCreateEvent === "boolean" ? currentProps.enableQuickCreateEvent : true,
12181
+ weekStart: typeof currentProps.weekStart === "number" ? currentProps.weekStart : 1
12182
+ };
12183
+ }
12184
+ async ensureCalendarBlockPopupHosts(blockNode, transaction) {
12185
+ var _a;
12186
+ if (!(blockNode == null ? void 0 : blockNode.uid) || blockNode.use !== "CalendarBlockModel") {
12187
+ return blockNode;
12188
+ }
12189
+ const resourceInit = this.getCalendarBlockResourceInit(blockNode);
12190
+ let changed = false;
12191
+ for (const actionKey of CALENDAR_POPUP_ACTION_KEYS) {
12192
+ const existing = (0, import_service_utils.getSingleNodeSubModel)((_a = blockNode.subModels) == null ? void 0 : _a[actionKey]);
12193
+ const expectedUid = this.getCalendarPopupActionUid(blockNode.uid, actionKey);
12194
+ const expectedUse = this.getCalendarPopupActionUse(actionKey);
12195
+ const openView = this.buildCalendarPopupOpenView({
12196
+ blockNode,
12197
+ actionKey,
12198
+ resourceInit
12199
+ });
12200
+ const currentOpenView = this.resolvePopupHostOpenView(existing);
12201
+ const shouldReplaceExisting = (existing == null ? void 0 : existing.uid) && existing.uid !== expectedUid;
12202
+ const shouldUpsert = !(existing == null ? void 0 : existing.uid) || shouldReplaceExisting || existing.use !== expectedUse || !import_lodash.default.isEqual(currentOpenView, openView);
12203
+ if (!shouldUpsert) {
12204
+ continue;
12205
+ }
12206
+ if (shouldReplaceExisting) {
12207
+ await this.removeNodeTreeWithBindings(existing.uid, transaction);
12208
+ }
12209
+ if ((existing == null ? void 0 : existing.uid) && existing.uid === expectedUid && !import_lodash.default.isEqual(currentOpenView, openView)) {
12210
+ await this.reconcilePopupOpenViewTransition(expectedUid, currentOpenView, openView, transaction);
12211
+ }
12212
+ const nextActionNode = {
12213
+ ...(existing == null ? void 0 : existing.uid) && existing.uid === expectedUid ? import_lodash.default.cloneDeep(existing) : {},
12214
+ uid: expectedUid,
12215
+ use: expectedUse,
12216
+ stepParams: import_lodash.default.merge({}, (existing == null ? void 0 : existing.uid) === expectedUid ? import_lodash.default.cloneDeep(existing.stepParams || {}) : {}, {
12217
+ popupSettings: {
12218
+ openView
12219
+ }
12220
+ })
12221
+ };
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;
12232
+ }
12233
+ if (!changed) {
12234
+ return blockNode;
12235
+ }
12236
+ return this.repository.findModelById(blockNode.uid, {
12237
+ transaction,
12238
+ includeAsyncNode: true
12239
+ });
12240
+ }
12241
+ async ensureCalendarBlockPopupHostsInTree(node, transaction) {
12242
+ if (!node || typeof node !== "object") {
12243
+ return node;
12244
+ }
12245
+ const current = node;
12246
+ if (current.use === "CalendarBlockModel") {
12247
+ return await this.ensureCalendarBlockPopupHosts(current, transaction);
12248
+ }
12249
+ for (const [subKey, value] of Object.entries(current.subModels || {})) {
12250
+ if (Array.isArray(value)) {
12251
+ const nextItems = [];
12252
+ let changed = false;
12253
+ for (const item of value) {
12254
+ const nextItem = await this.ensureCalendarBlockPopupHostsInTree(item, transaction);
12255
+ nextItems.push(nextItem);
12256
+ changed = changed || nextItem !== item;
12257
+ }
12258
+ if (changed) {
12259
+ current.subModels[subKey] = nextItems;
12260
+ }
12261
+ continue;
12262
+ }
12263
+ const nextValue = await this.ensureCalendarBlockPopupHostsInTree(value, transaction);
12264
+ if (nextValue !== value) {
12265
+ current.subModels[subKey] = nextValue;
12266
+ }
12267
+ }
12268
+ return current;
12269
+ }
12270
+ validateCalendarBlockState(actionName, node) {
12271
+ var _a;
12272
+ if ((node == null ? void 0 : node.use) !== "CalendarBlockModel") {
12273
+ return;
12274
+ }
12275
+ const resourceInit = this.getCalendarBlockResourceInit(node);
12276
+ const { collection, collectionName } = this.assertCalendarCollectionCompatible(actionName, resourceInit);
12277
+ const fieldNames = ((_a = node == null ? void 0 : node.props) == null ? void 0 : _a.fieldNames) || {};
12278
+ const checks = [
12279
+ ["titleField", fieldNames.title],
12280
+ ["startField", fieldNames.start],
12281
+ ["endField", fieldNames.end],
12282
+ ["colorField", fieldNames.colorFieldName]
12283
+ ];
12284
+ for (const [kind, rawFieldPath] of checks) {
12285
+ if (import_lodash.default.isUndefined(rawFieldPath) || import_lodash.default.isNull(rawFieldPath) || rawFieldPath === "") {
12286
+ continue;
12287
+ }
12288
+ const fieldPath = this.normalizeCalendarFieldPathInput(
12289
+ rawFieldPath,
12290
+ `flowSurfaces ${actionName} calendar ${kind}`,
12291
+ {
12292
+ allowEmpty: kind === "colorField" || kind === "endField"
12293
+ }
12294
+ );
12295
+ if (!fieldPath) {
12296
+ continue;
12297
+ }
12298
+ this.assertCalendarFieldBinding({
12299
+ actionName,
12300
+ collection,
12301
+ collectionName,
12302
+ fieldPath,
12303
+ kind
12304
+ });
12305
+ }
12306
+ }
10676
12307
  async resolveFieldDefinition(input) {
10677
12308
  const collection = this.getCollection(input.dataSourceKey, input.collectionName);
10678
12309
  const parsed = this.parseFieldPath(
@@ -10898,7 +12529,7 @@ class FlowSurfacesService {
10898
12529
  });
10899
12530
  const openView = this.resolvePopupHostOpenView(hostNode);
10900
12531
  const externalPopupHostUid = this.resolveExternalPopupHostUid(parentUid, openView);
10901
- if (externalPopupHostUid && String((openView == null ? void 0 : openView.popupTemplateUid) || "").trim() && !(openView == null ? void 0 : openView.popupTemplateContext)) {
12532
+ if (externalPopupHostUid && this.isReferencedPopupTemplateOpenView(openView, parentUid) && !this.isEditableDefaultActionPopupTemplateReference(hostNode, openView)) {
10902
12533
  (0, import_errors.throwBadRequest)(
10903
12534
  `flowSurfaces popup surface '${parentUid}' uses a popup template reference; convert it to copy before editing popup blocks`,
10904
12535
  "FLOW_SURFACE_TEMPLATE_REFERENCE_REQUIRED"
@@ -11326,16 +12957,17 @@ class FlowSurfacesService {
11326
12957
  }
11327
12958
  async loadResolvedNode(resolved, transaction) {
11328
12959
  var _a;
12960
+ let node;
11329
12961
  if ((resolved == null ? void 0 : resolved.kind) === "page" && (resolved == null ? void 0 : resolved.pageRoute)) {
11330
- return this.routeSync.buildPageTree(resolved.pageRoute, transaction);
11331
- }
11332
- if ((resolved == null ? void 0 : resolved.kind) === "tab" && (resolved == null ? void 0 : resolved.tabRoute)) {
11333
- return this.routeSync.buildTabAnchor(resolved.tabRoute, transaction);
11334
- }
11335
- if ((_a = resolved == null ? void 0 : resolved.node) == null ? void 0 : _a.uid) {
11336
- return resolved.node;
12962
+ node = await this.routeSync.buildPageTree(resolved.pageRoute, transaction);
12963
+ } else if ((resolved == null ? void 0 : resolved.kind) === "tab" && (resolved == null ? void 0 : resolved.tabRoute)) {
12964
+ node = await this.routeSync.buildTabAnchor(resolved.tabRoute, transaction);
12965
+ } else if ((_a = resolved == null ? void 0 : resolved.node) == null ? void 0 : _a.uid) {
12966
+ node = resolved.node;
12967
+ } else {
12968
+ node = await this.repository.findModelById(resolved.uid, { transaction, includeAsyncNode: true });
11337
12969
  }
11338
- return this.repository.findModelById(resolved.uid, { transaction, includeAsyncNode: true });
12970
+ return this.ensureCalendarBlockPopupHostsInTree(node, transaction);
11339
12971
  }
11340
12972
  normalizePopupTreeShape(node) {
11341
12973
  if (!node || typeof node !== "object") {