@nocobase/plugin-flow-engine 2.2.0-alpha.1 → 2.2.0-alpha.3

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 (66) hide show
  1. package/dist/client/index.js +1 -1
  2. package/dist/externalVersion.js +9 -9
  3. package/dist/locale/en-US.json +1 -0
  4. package/dist/locale/index.d.ts +2 -0
  5. package/dist/locale/zh-CN.json +1 -0
  6. package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
  7. package/dist/node_modules/acorn/package.json +1 -1
  8. package/dist/node_modules/acorn-jsx/package.json +1 -1
  9. package/dist/node_modules/acorn-walk/package.json +1 -1
  10. package/dist/node_modules/ses/package.json +1 -1
  11. package/dist/node_modules/zod/package.json +1 -1
  12. package/dist/server/flow-surfaces/{runjs-authoring/blocked-global-stop/index.d.ts → approval/authoring-validation.d.ts} +1 -2
  13. package/dist/server/flow-surfaces/approval/authoring-validation.js +1151 -0
  14. package/dist/server/flow-surfaces/approval/blueprint-service.js +2 -0
  15. package/dist/server/flow-surfaces/authoring-validation.js +471 -47
  16. package/dist/server/flow-surfaces/blueprint/export-document.d.ts +50 -0
  17. package/dist/server/flow-surfaces/blueprint/export-document.js +2510 -0
  18. package/dist/server/flow-surfaces/builder.js +16 -1
  19. package/dist/server/flow-surfaces/catalog.js +13 -2
  20. package/dist/server/flow-surfaces/configure-options.js +5 -3
  21. package/dist/server/flow-surfaces/constants.d.ts +9 -2
  22. package/dist/server/flow-surfaces/constants.js +1 -0
  23. package/dist/server/flow-surfaces/contract-guard.js +24 -2
  24. package/dist/server/flow-surfaces/default-action-popup.d.ts +2 -0
  25. package/dist/server/flow-surfaces/default-action-popup.js +27 -13
  26. package/dist/server/flow-surfaces/filter-group.d.ts +19 -2
  27. package/dist/server/flow-surfaces/filter-group.js +232 -3
  28. package/dist/server/flow-surfaces/planning/compiler.d.ts +1 -0
  29. package/dist/server/flow-surfaces/planning/compiler.js +205 -82
  30. package/dist/server/flow-surfaces/planning/key-registry.d.ts +1 -1
  31. package/dist/server/flow-surfaces/planning/runtime.js +1 -0
  32. package/dist/server/flow-surfaces/planning/step-link.d.ts +1 -1
  33. package/dist/server/flow-surfaces/planning/step-link.js +22 -3
  34. package/dist/server/flow-surfaces/public-data-surface-default-filter.js +0 -9
  35. package/dist/server/flow-surfaces/reaction/field-value.d.ts +9 -0
  36. package/dist/server/flow-surfaces/reaction/field-value.js +51 -2
  37. package/dist/server/flow-surfaces/reaction/linkage.d.ts +6 -1
  38. package/dist/server/flow-surfaces/reaction/linkage.js +18 -3
  39. package/dist/server/flow-surfaces/reaction/meta.js +19 -1
  40. package/dist/server/flow-surfaces/reaction/types.d.ts +19 -0
  41. package/dist/server/flow-surfaces/relation-backing-foreign-key.d.ts +10 -0
  42. package/dist/server/flow-surfaces/relation-backing-foreign-key.js +79 -0
  43. package/dist/server/flow-surfaces/runjs-authoring/ast/source.d.ts +1 -0
  44. package/dist/server/flow-surfaces/runjs-authoring/ast/source.js +20 -0
  45. package/dist/server/flow-surfaces/runjs-authoring/rules.js +0 -2
  46. package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.d.ts +0 -1
  47. package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.js +11 -19
  48. package/dist/server/flow-surfaces/runjs-authoring/runtime/types.d.ts +0 -12
  49. package/dist/server/flow-surfaces/runjs-authoring/scan/filter.js +12 -2
  50. package/dist/server/flow-surfaces/runjs-authoring/scan/index.d.ts +0 -14
  51. package/dist/server/flow-surfaces/runjs-authoring/scan/index.js +10 -8
  52. package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.d.ts +0 -14
  53. package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.js +18 -73
  54. package/dist/server/flow-surfaces/runjs-authoring/types.d.ts +1 -1
  55. package/dist/server/flow-surfaces/runjs-authoring/validators/index.js +9 -53
  56. package/dist/server/flow-surfaces/service.d.ts +42 -0
  57. package/dist/server/flow-surfaces/service.js +741 -100
  58. package/dist/server/flow-surfaces/types.d.ts +2 -1
  59. package/dist/server/variables/registry.js +3 -0
  60. package/dist/swagger/flow-surfaces.d.ts +181 -0
  61. package/dist/swagger/flow-surfaces.examples.d.ts +11 -0
  62. package/dist/swagger/flow-surfaces.examples.js +11 -0
  63. package/dist/swagger/flow-surfaces.js +161 -4
  64. package/dist/swagger/index.d.ts +181 -0
  65. package/package.json +2 -2
  66. package/dist/server/flow-surfaces/runjs-authoring/blocked-global-stop/index.js +0 -40
@@ -56,6 +56,7 @@ var import_executor = require("./executor");
56
56
  var import_reference_guards = require("./reference-guards");
57
57
  var import_key_registry = require("./planning/key-registry");
58
58
  var import_blueprint = require("./blueprint");
59
+ var import_export_document = require("./blueprint/export-document");
59
60
  var import_compile_blocks = require("./blueprint/compile-blocks");
60
61
  var import_default_block_actions = require("./default-block-actions");
61
62
  var import_template_reference = require("./template-reference");
@@ -96,6 +97,7 @@ var import_meta = require("./reaction/meta");
96
97
  var import_resolver = require("./reaction/resolver");
97
98
  var import_association_title_field = require("./association-title-field");
98
99
  var import_default_action_popup = require("./default-action-popup");
100
+ var import_relation_backing_foreign_key = require("./relation-backing-foreign-key");
99
101
  var import_defaults = require("./blueprint/defaults");
100
102
  var import_service_utils = require("./service-utils");
101
103
  var import_field_type_resolver = require("./field-type-resolver");
@@ -229,9 +231,11 @@ function isFlowSurfaceChartRepairError(error) {
229
231
  var _a, _b;
230
232
  return error instanceof import_errors.FlowSurfaceBadRequestError && ((_b = (_a = error.options) == null ? void 0 : _a.details) == null ? void 0 : _b.repairHint) === FLOW_SURFACE_CHART_REPAIR_HINT;
231
233
  }
234
+ const FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE = "exportBlueprint v1 only supports root page export";
232
235
  const FORM_BLOCK_USES = /* @__PURE__ */ new Set(["FormBlockModel", "CreateFormModel", "EditFormModel", ...import_approval.APPROVAL_FORM_BLOCK_USES]);
233
236
  const AUTO_SUBMIT_FORM_BLOCK_USES = /* @__PURE__ */ new Set(["CreateFormModel", "EditFormModel"]);
234
237
  const FLOW_SURFACE_DEFAULT_ACTION_SETTINGS_KEYS = /* @__PURE__ */ new Set(["filter"]);
238
+ const ACTION_BUTTON_GENERAL_SETTING_KEYS = ["title", "tooltip", "icon", "iconOnly", "type", "danger", "color"];
235
239
  const DETAILS_BLOCK_USES = /* @__PURE__ */ new Set(["DetailsBlockModel", ...import_approval.APPROVAL_DETAILS_BLOCK_USES]);
236
240
  const SIMPLE_FORM_BLOCK_USES = /* @__PURE__ */ new Set([
237
241
  "FormBlockModel",
@@ -685,6 +689,7 @@ function assertNoFlowSurfaceIdTitleFieldSettings(value, options = {}) {
685
689
  };
686
690
  visit(value, options.basePath || []);
687
691
  }
692
+ const DEFAULT_ADMIN_UI_LAYOUT_UID = "admin-layout-model";
688
693
  class FlowSurfacesService {
689
694
  constructor(plugin) {
690
695
  this.plugin = plugin;
@@ -1026,6 +1031,101 @@ class FlowSurfacesService {
1026
1031
  ...extras
1027
1032
  };
1028
1033
  }
1034
+ hasDesktopRouteUiLayoutsRelation() {
1035
+ var _a, _b;
1036
+ try {
1037
+ return !!this.db.getCollection("uiLayouts") && !!((_b = (_a = this.db.getCollection("desktopRoutes")) == null ? void 0 : _a.getField) == null ? void 0 : _b.call(_a, "uiLayouts"));
1038
+ } catch (error) {
1039
+ return false;
1040
+ }
1041
+ }
1042
+ normalizeDesktopRouteRelationId(routeId) {
1043
+ return import_lodash.default.isNil(routeId) ? void 0 : routeId;
1044
+ }
1045
+ async readDesktopRouteUiLayoutUids(routeId, transaction) {
1046
+ const relationRouteId = this.normalizeDesktopRouteRelationId(routeId);
1047
+ if (import_lodash.default.isUndefined(relationRouteId) || !this.hasDesktopRouteUiLayoutsRelation()) {
1048
+ return [];
1049
+ }
1050
+ const uiLayouts = await this.db.getRepository("desktopRoutes.uiLayouts", relationRouteId).find({
1051
+ fields: ["uid"],
1052
+ transaction
1053
+ });
1054
+ return import_lodash.default.uniq(
1055
+ uiLayouts.map((uiLayout) => {
1056
+ var _a;
1057
+ return String(((_a = uiLayout == null ? void 0 : uiLayout.get) == null ? void 0 : _a.call(uiLayout, "uid")) || (uiLayout == null ? void 0 : uiLayout.uid) || "").trim();
1058
+ }).filter(Boolean)
1059
+ );
1060
+ }
1061
+ async resolveDefaultDesktopRouteUiLayoutUids(transaction) {
1062
+ if (!this.hasDesktopRouteUiLayoutsRelation()) {
1063
+ return [];
1064
+ }
1065
+ const defaultLayout = await this.db.getRepository("uiLayouts").findOne({
1066
+ filter: {
1067
+ uid: DEFAULT_ADMIN_UI_LAYOUT_UID,
1068
+ enabled: true
1069
+ },
1070
+ transaction
1071
+ });
1072
+ return defaultLayout ? [DEFAULT_ADMIN_UI_LAYOUT_UID] : [];
1073
+ }
1074
+ async resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction) {
1075
+ const parentRouteId = this.readRouteField(parentRoute, "id");
1076
+ if (!import_lodash.default.isNil(parentRouteId)) {
1077
+ const parentLayoutUids = await this.readDesktopRouteUiLayoutUids(parentRouteId, transaction);
1078
+ if (parentLayoutUids.length) {
1079
+ return parentLayoutUids;
1080
+ }
1081
+ }
1082
+ return this.resolveDefaultDesktopRouteUiLayoutUids(transaction);
1083
+ }
1084
+ async setDesktopRouteUiLayouts(routeId, uiLayoutUids, transaction) {
1085
+ const relationRouteId = this.normalizeDesktopRouteRelationId(routeId);
1086
+ if (import_lodash.default.isUndefined(relationRouteId) || !uiLayoutUids.length || !this.hasDesktopRouteUiLayoutsRelation()) {
1087
+ return;
1088
+ }
1089
+ await this.db.getRepository("desktopRoutes.uiLayouts", relationRouteId).set({
1090
+ tk: uiLayoutUids,
1091
+ transaction
1092
+ });
1093
+ }
1094
+ async attachDesktopRouteUiLayoutsToRouteAndChildren(routeId, uiLayoutUids, transaction) {
1095
+ if (import_lodash.default.isNil(routeId) || !uiLayoutUids.length || !this.hasDesktopRouteUiLayoutsRelation()) {
1096
+ return;
1097
+ }
1098
+ await this.setDesktopRouteUiLayouts(routeId, uiLayoutUids, transaction);
1099
+ const children = await this.db.getRepository("desktopRoutes").find({
1100
+ fields: ["id"],
1101
+ filter: {
1102
+ parentId: routeId
1103
+ },
1104
+ transaction
1105
+ });
1106
+ for (const child of children) {
1107
+ await this.attachDesktopRouteUiLayoutsToRouteAndChildren(
1108
+ this.readRouteField(child, "id"),
1109
+ uiLayoutUids,
1110
+ transaction
1111
+ );
1112
+ }
1113
+ }
1114
+ async ensureDesktopRouteUiLayouts(route, transaction) {
1115
+ const routeId = this.readRouteField(route, "id");
1116
+ if (import_lodash.default.isNil(routeId) || !this.hasDesktopRouteUiLayoutsRelation()) {
1117
+ return [];
1118
+ }
1119
+ const existingLayoutUids = await this.readDesktopRouteUiLayoutUids(routeId, transaction);
1120
+ if (existingLayoutUids.length) {
1121
+ return existingLayoutUids;
1122
+ }
1123
+ const parentRouteId = this.readRouteField(route, "parentId");
1124
+ const parentRoute = import_lodash.default.isNil(parentRouteId) ? null : await this.findMenuRouteById(parentRouteId, transaction);
1125
+ const inheritedLayoutUids = await this.resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction);
1126
+ await this.setDesktopRouteUiLayouts(routeId, inheritedLayoutUids, transaction);
1127
+ return inheritedLayoutUids;
1128
+ }
1029
1129
  isValidMenuIconName(value) {
1030
1130
  const normalized = String(value || "").trim();
1031
1131
  return !!normalized && ANT_DESIGN_ICON_NAMES.has(normalized);
@@ -1107,7 +1207,7 @@ class FlowSurfacesService {
1107
1207
  this.assertVisibleNavigationIcon("createMenu", "values", values);
1108
1208
  const schemaUid = values.schemaUid || (0, import_utils.uid)();
1109
1209
  const desktopRoutes = this.db.getRepository("desktopRoutes");
1110
- await desktopRoutes.create({
1210
+ const route = await desktopRoutes.create({
1111
1211
  values: {
1112
1212
  type: "group",
1113
1213
  sort: this.allocateRouteSortValue(),
@@ -1120,10 +1220,11 @@ class FlowSurfacesService {
1120
1220
  },
1121
1221
  transaction
1122
1222
  });
1123
- const route = await desktopRoutes.findOne({
1124
- filter: { schemaUid },
1223
+ await this.attachDesktopRouteUiLayoutsToRouteAndChildren(
1224
+ this.readRouteField(route, "id"),
1225
+ await this.resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction),
1125
1226
  transaction
1126
- });
1227
+ );
1127
1228
  return this.buildMenuResult(route);
1128
1229
  }
1129
1230
  async createFlowMenuItem(values, transaction) {
@@ -1138,7 +1239,7 @@ class FlowSurfacesService {
1138
1239
  const title = values.title || pageSchemaUid;
1139
1240
  const tabTitle = values.tabTitle || "Untitled";
1140
1241
  const desktopRoutes = this.db.getRepository("desktopRoutes");
1141
- await desktopRoutes.create({
1242
+ const createdRoute = await desktopRoutes.create({
1142
1243
  values: {
1143
1244
  type: "flowPage",
1144
1245
  sort: this.allocateRouteSortValue(),
@@ -1173,6 +1274,11 @@ class FlowSurfacesService {
1173
1274
  },
1174
1275
  transaction
1175
1276
  });
1277
+ await this.attachDesktopRouteUiLayoutsToRouteAndChildren(
1278
+ this.readRouteField(createdRoute, "id"),
1279
+ await this.resolveInheritedDesktopRouteUiLayoutUids(parentRoute, transaction),
1280
+ transaction
1281
+ );
1176
1282
  const route = await desktopRoutes.findOne({
1177
1283
  filter: { schemaUid: pageSchemaUid },
1178
1284
  appends: ["children"],
@@ -1945,6 +2051,9 @@ class FlowSurfacesService {
1945
2051
  if (!(popupProfile == null ? void 0 : popupProfile.currentCollection)) {
1946
2052
  return popupProfile == null ? void 0 : popupProfile.filterByTk;
1947
2053
  }
2054
+ if (popupProfile.popupKind === "recordPopup" && popupProfile.popupHostUse && POPUP_HOST_DEFAULT_RECORD_CONTEXT_ACTION_USES.has(popupProfile.popupHostUse)) {
2055
+ return "{{ctx.view.inputArgs.filterByTk}}";
2056
+ }
1948
2057
  if (popupProfile.popupKind !== "associationPopup") {
1949
2058
  return popupProfile.filterByTk;
1950
2059
  }
@@ -2300,10 +2409,18 @@ class FlowSurfacesService {
2300
2409
  if (!sameCurrentCollection || !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.filterByTk)) {
2301
2410
  return false;
2302
2411
  }
2412
+ const expectedFilterByTk = this.resolvePopupCurrentRecordResourceFilterByTk(input.popupProfile, {
2413
+ usePopupInputArgsWhenSourceIdInferred: true
2414
+ });
2415
+ const matchesCurrentRecordFilterByTk = this.isPopupCurrentRecordFilterByTkMatch(
2416
+ input.popupProfile,
2417
+ normalized.filterByTk,
2418
+ expectedFilterByTk
2419
+ );
2303
2420
  if (input.popupProfile.hasAssociationContext) {
2304
- return this.isSameConfiguredFlowContextValue(normalized.filterByTk, input.popupProfile.filterByTk) && normalized.associationName === input.popupProfile.associationName && this.isSameConfiguredFlowContextValue(normalized.sourceId, input.popupProfile.sourceId);
2421
+ return matchesCurrentRecordFilterByTk && normalized.associationName === input.popupProfile.associationName && this.isSameConfiguredFlowContextValue(normalized.sourceId, input.popupProfile.sourceId);
2305
2422
  }
2306
- return this.isSameConfiguredFlowContextValue(normalized.filterByTk, input.popupProfile.filterByTk) && !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.associationName) && !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.sourceId);
2423
+ return matchesCurrentRecordFilterByTk && !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.associationName) && !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.sourceId);
2307
2424
  }
2308
2425
  if (input.binding === "associatedRecords") {
2309
2426
  if (!(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.collectionName) || !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.associationName) || !(0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.sourceId) || (0, import_service_helpers.hasConfiguredFlowContextValue)(normalized.filterByTk)) {
@@ -2346,6 +2463,12 @@ class FlowSurfacesService {
2346
2463
  }
2347
2464
  return import_lodash.default.isEqual(this.normalizeFlowContextTemplateValue(left), this.normalizeFlowContextTemplateValue(right));
2348
2465
  }
2466
+ isPopupCurrentRecordFilterByTkMatch(popupProfile, filterByTk, expectedFilterByTk) {
2467
+ if (this.isSameConfiguredFlowContextValue(filterByTk, expectedFilterByTk)) {
2468
+ return true;
2469
+ }
2470
+ return popupProfile.popupKind === "associationPopup" && this.isSameConfiguredFlowContextValue(filterByTk, popupProfile.filterByTk);
2471
+ }
2349
2472
  isPopupAssociatedRecordsSourceIdMatch(popupProfile, associationField, sourceId) {
2350
2473
  var _a, _b;
2351
2474
  if (!(0, import_service_helpers.hasConfiguredFlowContextValue)(sourceId)) {
@@ -2621,6 +2744,28 @@ class FlowSurfacesService {
2621
2744
  }
2622
2745
  return capability;
2623
2746
  }
2747
+ async getLiveFieldValueCapability(writeTarget, resolvedTarget, node, options = {}) {
2748
+ const context = await this.context(
2749
+ {
2750
+ target: writeTarget
2751
+ },
2752
+ options
2753
+ );
2754
+ const { capabilities } = (0, import_meta.buildReactionMetaCapabilities)({
2755
+ resolvedTarget: {
2756
+ ...resolvedTarget,
2757
+ node
2758
+ },
2759
+ context
2760
+ });
2761
+ const capability = capabilities.find((item) => item.kind === "fieldValue");
2762
+ if (!capability) {
2763
+ (0, import_errors.throwBadRequest)(
2764
+ `flowSurfaces reaction target '${resolvedTarget.use || resolvedTarget.target.uid}' does not support fieldValue`
2765
+ );
2766
+ }
2767
+ return capability;
2768
+ }
2624
2769
  async getReactionMeta(values, options = {}) {
2625
2770
  (0, import_payload_shape.validateFlowSurfacePayloadShape)("getReactionMeta", values, "values");
2626
2771
  const { writeTarget, node, resolvedTarget } = await this.resolveReactionRequest("getReactionMeta", values == null ? void 0 : values.target, {
@@ -2666,6 +2811,8 @@ class FlowSurfacesService {
2666
2811
  },
2667
2812
  rules: Array.isArray(values == null ? void 0 : values.rules) ? values.rules : []
2668
2813
  });
2814
+ const liveCapability = await this.getLiveFieldValueCapability(writeTarget, resolvedTarget, node, options);
2815
+ (0, import_field_value.validateFieldValueRulesAgainstCapability)(result.normalizedRules, liveCapability);
2669
2816
  await this.persistReactionSlot(storageNode, capability.resolvedSlot, result.canonicalRules, options);
2670
2817
  return result;
2671
2818
  }
@@ -2873,6 +3020,41 @@ class FlowSurfacesService {
2873
3020
  const publicNode = this.stripInternalSurfaceMetaFromNodeTree(import_lodash.default.cloneDeep(rawNode));
2874
3021
  return this.buildSurfaceReadPayload(target, resolved, publicNode, options);
2875
3022
  }
3023
+ async exportBlueprint(input, options = {}) {
3024
+ const request = this.normalizeExportBlueprintRequest(input);
3025
+ const resolved = await this.locator.resolve(request.target, options);
3026
+ if (resolved.kind !== "page" || !resolved.pageRoute) {
3027
+ (0, import_errors.throwBadRequest)(FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE);
3028
+ }
3029
+ const pageSchemaUid = this.resolveExportBlueprintPageSchemaUid(request.target, resolved);
3030
+ await this.assertExportBlueprintRootTarget(request.target, resolved, pageSchemaUid, options.transaction);
3031
+ const rawNode = await this.decorateTemplateReadbackTree(
3032
+ this.normalizePopupTreeShape(
3033
+ await this.loadResolvedNode(resolved, options.transaction, {
3034
+ persistCalendarPopupHosts: false
3035
+ })
3036
+ ),
3037
+ options.transaction
3038
+ );
3039
+ if (!(rawNode == null ? void 0 : rawNode.uid)) {
3040
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint target '${pageSchemaUid}' could not resolve a readable page tree`);
3041
+ }
3042
+ const pageRoute = resolved.pageRoute ? await this.routeSync.hydrateRoute(resolved.pageRoute, options.transaction) : void 0;
3043
+ const result = (0, import_export_document.exportFlowSurfaceBlueprintDocument)({
3044
+ page: rawNode,
3045
+ pageRoute,
3046
+ target: {
3047
+ pageSchemaUid
3048
+ },
3049
+ unsupportedPolicy: request.unsupportedPolicy
3050
+ });
3051
+ return {
3052
+ ...result,
3053
+ document: (0, import_blueprint.prepareFlowSurfaceApplyBlueprintDocument)(
3054
+ result.document
3055
+ )
3056
+ };
3057
+ }
2876
3058
  getDeclaredKeyPersistenceDeps() {
2877
3059
  return {
2878
3060
  findModelById: (uid2, findOptions) => this.repository.findModelById(uid2, findOptions),
@@ -4474,10 +4656,16 @@ class FlowSurfacesService {
4474
4656
  return this.buildPopupTemplateOpenView(template, "reference", templateTargetUid, options);
4475
4657
  }
4476
4658
  shouldHydrateDetachedPopupTemplateBlockResourceContext(blockNode, context) {
4477
- if (!this.isCollectionBlockUse(blockNode == null ? void 0 : blockNode.use) || !context.associationName || !context.sourceId) {
4659
+ if (!this.isCollectionBlockUse(blockNode == null ? void 0 : blockNode.use)) {
4478
4660
  return false;
4479
4661
  }
4480
4662
  const init = import_lodash.default.get(blockNode, ["stepParams", "resourceSettings", "init"]) || {};
4663
+ if (this.resolveDetachedPopupTemplateBlockCurrentRecordFilterByTk(init, context)) {
4664
+ return true;
4665
+ }
4666
+ if (!context.associationName || !context.sourceId) {
4667
+ return false;
4668
+ }
4481
4669
  const popupDataSourceKey = context.dataSourceKey || "main";
4482
4670
  const blockDataSourceKey = init.dataSourceKey || "main";
4483
4671
  if (!context.collectionName || blockDataSourceKey !== popupDataSourceKey || init.collectionName !== context.collectionName) {
@@ -4492,6 +4680,28 @@ class FlowSurfacesService {
4492
4680
  }
4493
4681
  return blockAssociationName !== context.associationName || !this.isSameConfiguredFlowContextValue(init.sourceId, context.sourceId);
4494
4682
  }
4683
+ resolveDetachedPopupTemplateBlockCurrentRecordFilterByTk(init, context) {
4684
+ if (!(0, import_service_helpers.hasConfiguredFlowContextValue)(init.filterByTk)) {
4685
+ return void 0;
4686
+ }
4687
+ if (this.isSameConfiguredFlowContextValue(init.filterByTk, "{{ctx.view.inputArgs.filterByTk}}")) {
4688
+ return void 0;
4689
+ }
4690
+ const popupDataSourceKey = context.dataSourceKey || "main";
4691
+ const blockDataSourceKey = init.dataSourceKey || "main";
4692
+ if (!context.collectionName || blockDataSourceKey !== popupDataSourceKey || init.collectionName !== context.collectionName) {
4693
+ return void 0;
4694
+ }
4695
+ if (context.filterByTk && this.isSameConfiguredFlowContextValue(init.filterByTk, context.filterByTk)) {
4696
+ return "{{ctx.view.inputArgs.filterByTk}}";
4697
+ }
4698
+ const collection = this.getCollection(popupDataSourceKey, context.collectionName);
4699
+ const filterTargetKey = this.getCollectionFilterTargetKey(collection);
4700
+ if (this.isSameConfiguredFlowContextValue(init.filterByTk, `{{ctx.record.${filterTargetKey}}}`)) {
4701
+ return "{{ctx.view.inputArgs.filterByTk}}";
4702
+ }
4703
+ return void 0;
4704
+ }
4495
4705
  collectDetachedPopupTemplateBlockResourceContextPatches(node, context, patches = []) {
4496
4706
  if (!node || typeof node !== "object") {
4497
4707
  return patches;
@@ -4499,6 +4709,7 @@ class FlowSurfacesService {
4499
4709
  if (node.uid && this.shouldHydrateDetachedPopupTemplateBlockResourceContext(node, context)) {
4500
4710
  const nextStepParams = import_lodash.default.cloneDeep(node.stepParams || {});
4501
4711
  const currentInit = import_lodash.default.get(nextStepParams, ["resourceSettings", "init"]) || {};
4712
+ const filterByTk = this.resolveDetachedPopupTemplateBlockCurrentRecordFilterByTk(currentInit, context);
4502
4713
  import_lodash.default.set(
4503
4714
  nextStepParams,
4504
4715
  ["resourceSettings", "init"],
@@ -4506,8 +4717,11 @@ class FlowSurfacesService {
4506
4717
  ...currentInit,
4507
4718
  dataSourceKey: context.dataSourceKey || currentInit.dataSourceKey || "main",
4508
4719
  collectionName: context.collectionName || currentInit.collectionName,
4509
- associationName: context.associationName,
4510
- sourceId: context.sourceId
4720
+ ...context.associationName && context.sourceId ? {
4721
+ associationName: context.associationName,
4722
+ sourceId: context.sourceId
4723
+ } : {},
4724
+ ...filterByTk ? { filterByTk } : {}
4511
4725
  })
4512
4726
  );
4513
4727
  patches.push({
@@ -5767,7 +5981,7 @@ class FlowSurfacesService {
5767
5981
  (0, import_errors.throwBadRequest)("flowSurfaces updateMenu requires menuRouteId");
5768
5982
  }
5769
5983
  const route = await this.assertMenuRouteUpdatable(menuRouteId, options.transaction);
5770
- await this.assertMenuParentIsGroup(values.parentMenuRouteId, options.transaction);
5984
+ const nextParentRoute = await this.assertMenuParentIsGroup(values.parentMenuRouteId, options.transaction);
5771
5985
  await this.assertMenuParentNotSelfOrDescendant(route, values.parentMenuRouteId, options.transaction);
5772
5986
  const nextOptions = { ...this.readRouteOptions(route) };
5773
5987
  const updateValues = {};
@@ -5798,6 +6012,13 @@ class FlowSurfacesService {
5798
6012
  });
5799
6013
  }
5800
6014
  const updated = await this.findMenuRouteById(menuRouteId, options.transaction);
6015
+ if (updated && Object.prototype.hasOwnProperty.call(values, "parentMenuRouteId")) {
6016
+ await this.attachDesktopRouteUiLayoutsToRouteAndChildren(
6017
+ this.readRouteField(updated, "id"),
6018
+ await this.resolveInheritedDesktopRouteUiLayoutUids(nextParentRoute, options.transaction),
6019
+ options.transaction
6020
+ );
6021
+ }
5801
6022
  return this.buildMenuResult(updated);
5802
6023
  }
5803
6024
  async initializeFlowPageForRoute(route, values, transaction) {
@@ -5805,6 +6026,7 @@ class FlowSurfacesService {
5805
6026
  const pageSchemaUid = this.readRouteField(route, "schemaUid");
5806
6027
  const structure = await this.loadRouteBackedPageStructure(route, transaction);
5807
6028
  let tabRoute = structure.tabRoutes[0];
6029
+ const routeUiLayoutUids = await this.ensureDesktopRouteUiLayouts(route, transaction);
5808
6030
  const routeOptions = this.readRouteOptions(route);
5809
6031
  if (!routeOptions[FLOW_SURFACE_MENU_BINDABLE_OPTION_KEY]) {
5810
6032
  (0, import_errors.throwBadRequest)(`flowSurfaces createPage only accepts a bindable menu route created by createMenu(type="item")`);
@@ -5826,7 +6048,7 @@ class FlowSurfacesService {
5826
6048
  const tabSchemaUid2 = values.tabSchemaUid || (0, import_utils.uid)();
5827
6049
  const tabSchemaName2 = values.tabSchemaName || (0, import_utils.uid)();
5828
6050
  const tabTitle = values.tabTitle || "Untitled";
5829
- await this.db.getRepository("desktopRoutes").create({
6051
+ tabRoute = await this.db.getRepository("desktopRoutes").create({
5830
6052
  values: {
5831
6053
  type: "tabs",
5832
6054
  sort: this.allocateRouteSortValue(1),
@@ -5843,10 +6065,7 @@ class FlowSurfacesService {
5843
6065
  },
5844
6066
  transaction
5845
6067
  });
5846
- tabRoute = await this.db.getRepository("desktopRoutes").findOne({
5847
- filter: { schemaUid: tabSchemaUid2 },
5848
- transaction
5849
- });
6068
+ await this.setDesktopRouteUiLayouts(this.readRouteField(tabRoute, "id"), routeUiLayoutUids, transaction);
5850
6069
  } else {
5851
6070
  await this.db.getRepository("desktopRoutes").update({
5852
6071
  filterByTk: String(this.readRouteField(tabRoute, "id")),
@@ -5870,6 +6089,9 @@ class FlowSurfacesService {
5870
6089
  transaction
5871
6090
  });
5872
6091
  }
6092
+ if (tabRoute) {
6093
+ await this.setDesktopRouteUiLayouts(this.readRouteField(tabRoute, "id"), routeUiLayoutUids, transaction);
6094
+ }
5873
6095
  await this.ensureFlowRoutePageSchemaShell(pageSchemaUid, transaction);
5874
6096
  await this.db.getRepository("desktopRoutes").update({
5875
6097
  filterByTk: String(routeId),
@@ -6009,6 +6231,11 @@ class FlowSurfacesService {
6009
6231
  },
6010
6232
  transaction: options.transaction
6011
6233
  });
6234
+ await this.setDesktopRouteUiLayouts(
6235
+ route.get("id"),
6236
+ await this.ensureDesktopRouteUiLayouts(pageRoute, options.transaction),
6237
+ options.transaction
6238
+ );
6012
6239
  const gridUid = await this.ensureGridChild(tabSchemaUid, "BlockGridModel", options.transaction);
6013
6240
  const result = {
6014
6241
  pageUid: pageTarget.uid,
@@ -6679,11 +6906,6 @@ class FlowSurfacesService {
6679
6906
  requiredFieldCount: options.requiredFieldCount
6680
6907
  }
6681
6908
  );
6682
- if (!(0, import_service_utils.hasOwnDefined)(normalizedSettings, "filterableFieldNames")) {
6683
- normalizedSettings.filterableFieldNames = (0, import_public_data_surface_default_filter.resolveFlowSurfaceDefaultFilterFieldNames)(
6684
- normalizedSettings.defaultFilter
6685
- );
6686
- }
6687
6909
  }
6688
6910
  return normalizedSettings;
6689
6911
  }
@@ -11417,6 +11639,7 @@ class FlowSurfacesService {
11417
11639
  }
11418
11640
  if (this.isAIEmployeeActionUse(current == null ? void 0 : current.use) && this.hasAIEmployeePublicSettings(normalizedValues)) {
11419
11641
  const enabledPackages = await this.resolveEnabledPluginPackages(options);
11642
+ const hasRawAIEmployeeStepTasks = import_lodash.default.has(normalizedValues, ["stepParams", ...AI_EMPLOYEE_TASK_STEP_PARAMS_PATH]);
11420
11643
  const aiEmployeeSettingsPayload = await this.normalizeAIEmployeeActionPublicSettings(
11421
11644
  "updateSettings",
11422
11645
  import_lodash.default.pick(normalizedValues, AI_EMPLOYEE_PUBLIC_SETTING_KEYS),
@@ -11429,7 +11652,8 @@ class FlowSurfacesService {
11429
11652
  promptContext: {
11430
11653
  kind: "target",
11431
11654
  targetUid: (current == null ? void 0 : current.uid) || writeTarget.uid
11432
- }
11655
+ },
11656
+ skipExistingTaskWorkContextRebase: hasRawAIEmployeeStepTasks
11433
11657
  }
11434
11658
  );
11435
11659
  AI_EMPLOYEE_PUBLIC_SETTING_KEYS.forEach((key) => {
@@ -11511,6 +11735,7 @@ class FlowSurfacesService {
11511
11735
  normalizedValues,
11512
11736
  nextPayload
11513
11737
  );
11738
+ this.syncActionButtonSettingsForUpdateSettings(current, normalizedValues, nextPayload);
11514
11739
  this.syncActionTriggerWorkflowsForUpdateSettings(current, normalizedValues, nextPayload);
11515
11740
  const popupActionContext = options.popupActionContext || await this.resolveRecordContextPopupActionContextForHost(current, options.transaction);
11516
11741
  await this.normalizeOpenViewForUpdateSettings(
@@ -11562,6 +11787,12 @@ class FlowSurfacesService {
11562
11787
  if (Object.keys(nextPayload).length === 1) {
11563
11788
  return { uid: current.uid };
11564
11789
  }
11790
+ await this.assertNoDuplicateAIEmployeeActionForUpdateSettings(
11791
+ options.openViewActionName || "updateSettings",
11792
+ current,
11793
+ effectiveNode,
11794
+ options.transaction
11795
+ );
11565
11796
  if (target.kind === "tab" && target.tabRoute) {
11566
11797
  await this.routeSync.persistTabSettings(target, current, nextPayload, options.transaction);
11567
11798
  return {
@@ -11972,17 +12203,6 @@ class FlowSurfacesService {
11972
12203
  const filterValue = this.normalizeEffectivePublicDataSurfaceDefaultFilter(normalizedFilterValue, {
11973
12204
  requiredFieldCount: options.requiredFieldCount
11974
12205
  });
11975
- if (!hasPropsFilterableFieldNames && !hasStepFilterableFieldNames) {
11976
- const filterableFieldNames = (0, import_public_data_surface_default_filter.resolveFlowSurfaceDefaultFilterFieldNames)(filterValue);
11977
- if (filterableFieldNames.length) {
11978
- nextProps.filterableFieldNames = filterableFieldNames;
11979
- import_lodash.default.set(
11980
- nextStepParams,
11981
- ["filterSettings", "filterableFieldNames", "filterableFieldNames"],
11982
- import_lodash.default.cloneDeep(filterableFieldNames)
11983
- );
11984
- }
11985
- }
11986
12206
  nextProps.defaultFilterValue = import_lodash.default.cloneDeep(filterValue);
11987
12207
  nextProps.filterValue = import_lodash.default.cloneDeep(filterValue);
11988
12208
  import_lodash.default.set(nextStepParams, ["filterSettings", "defaultFilter", "defaultFilter"], import_lodash.default.cloneDeep(filterValue));
@@ -12029,6 +12249,65 @@ class FlowSurfacesService {
12029
12249
  nextPayload.stepParams = nextStepParams;
12030
12250
  }
12031
12251
  }
12252
+ syncActionButtonSettingsForUpdateSettings(current, normalizedValues, nextPayload) {
12253
+ if (!this.supportsActionButtonSettingsSync(current)) {
12254
+ return;
12255
+ }
12256
+ const requestedProps = this.pickRequestedActionButtonSettings(normalizedValues.props);
12257
+ const requestedButtonGeneral = this.pickRequestedActionButtonSettings(
12258
+ import_lodash.default.get(normalizedValues, ["stepParams", "buttonSettings", "general"])
12259
+ );
12260
+ const hasRequestedProps = Object.keys(requestedProps).length > 0;
12261
+ const hasRequestedButtonGeneral = Object.keys(requestedButtonGeneral).length > 0;
12262
+ if (!hasRequestedProps && !hasRequestedButtonGeneral) {
12263
+ return;
12264
+ }
12265
+ const hasRequestedTitle = Object.prototype.hasOwnProperty.call(requestedProps, "title") || Object.prototype.hasOwnProperty.call(requestedButtonGeneral, "title");
12266
+ const shouldStripImplicitTitle = (requestedProps.iconOnly === true || requestedButtonGeneral.iconOnly === true) && !hasRequestedTitle;
12267
+ const nextProps = import_lodash.default.cloneDeep(
12268
+ import_lodash.default.isPlainObject(nextPayload.props) ? nextPayload.props : import_lodash.default.isPlainObject(current == null ? void 0 : current.props) ? current.props : {}
12269
+ );
12270
+ const nextStepParams = import_lodash.default.cloneDeep(
12271
+ import_lodash.default.isPlainObject(nextPayload.stepParams) ? nextPayload.stepParams : import_lodash.default.isPlainObject(current == null ? void 0 : current.stepParams) ? current.stepParams : {}
12272
+ );
12273
+ Object.entries(requestedProps).forEach(([key, value]) => {
12274
+ if (Object.prototype.hasOwnProperty.call(requestedButtonGeneral, key)) {
12275
+ return;
12276
+ }
12277
+ import_lodash.default.set(nextStepParams, ["buttonSettings", "general", key], import_lodash.default.cloneDeep(value));
12278
+ });
12279
+ Object.entries(requestedButtonGeneral).forEach(([key, value]) => {
12280
+ if (Object.prototype.hasOwnProperty.call(requestedProps, key)) {
12281
+ return;
12282
+ }
12283
+ nextProps[key] = import_lodash.default.cloneDeep(value);
12284
+ });
12285
+ if (shouldStripImplicitTitle) {
12286
+ delete nextProps.title;
12287
+ if (import_lodash.default.isPlainObject(import_lodash.default.get(nextStepParams, ["buttonSettings", "general"]))) {
12288
+ delete nextStepParams.buttonSettings.general.title;
12289
+ }
12290
+ }
12291
+ nextPayload.props = nextProps;
12292
+ nextPayload.stepParams = nextStepParams;
12293
+ }
12294
+ supportsActionButtonSettingsSync(current) {
12295
+ var _a, _b, _c, _d, _e, _f;
12296
+ const contract = (0, import_catalog.getNodeContract)(current == null ? void 0 : current.use);
12297
+ return ((_b = (_a = contract.domains.props) == null ? void 0 : _a.allowedKeys) == null ? void 0 : _b.includes("iconOnly")) && ((_f = (_e = (_d = (_c = contract.domains.stepParams) == null ? void 0 : _c.groups) == null ? void 0 : _d.buttonSettings) == null ? void 0 : _e.allowedPaths) == null ? void 0 : _f.includes("general.iconOnly"));
12298
+ }
12299
+ pickRequestedActionButtonSettings(input) {
12300
+ const picked = {};
12301
+ if (!import_lodash.default.isPlainObject(input)) {
12302
+ return picked;
12303
+ }
12304
+ ACTION_BUTTON_GENERAL_SETTING_KEYS.forEach((key) => {
12305
+ if (Object.prototype.hasOwnProperty.call(input, key) && !import_lodash.default.isUndefined(input[key])) {
12306
+ picked[key] = import_lodash.default.cloneDeep(input[key]);
12307
+ }
12308
+ });
12309
+ return picked;
12310
+ }
12032
12311
  syncCreatedFieldWrapperTitleFieldStepParams(node) {
12033
12312
  const mirror = (UPDATE_SETTINGS_STEP_PARAM_MIRRORS_BY_USE[(node == null ? void 0 : node.use) || ""] || []).find(
12034
12313
  (item) => item.domain === "props" && item.key === "titleField"
@@ -13694,6 +13973,111 @@ class FlowSurfacesService {
13694
13973
  }
13695
13974
  return target;
13696
13975
  }
13976
+ normalizeExportBlueprintRequest(input) {
13977
+ if (!import_lodash.default.isPlainObject(input)) {
13978
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint payload must be an object`);
13979
+ }
13980
+ const unsupportedKeys = Object.keys(input).filter((key) => key !== "target" && key !== "options");
13981
+ if (unsupportedKeys.length) {
13982
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint only accepts target and options`);
13983
+ }
13984
+ if (!import_lodash.default.isPlainObject(input.target)) {
13985
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint requires target`);
13986
+ }
13987
+ const targetInput = input.target;
13988
+ const target = (0, import_service_utils.buildDefinedPayload)({
13989
+ uid: this.normalizeExportBlueprintLocatorValue(targetInput.uid, "uid"),
13990
+ pageSchemaUid: this.normalizeExportBlueprintLocatorValue(targetInput.pageSchemaUid, "pageSchemaUid"),
13991
+ tabSchemaUid: this.normalizeExportBlueprintLocatorValue(targetInput.tabSchemaUid, "tabSchemaUid"),
13992
+ routeId: this.normalizeExportBlueprintLocatorValue(targetInput.routeId, "routeId")
13993
+ });
13994
+ const unsupportedTargetKeys = Object.keys(targetInput).filter(
13995
+ (key) => !["uid", "pageSchemaUid", "tabSchemaUid", "routeId"].includes(key)
13996
+ );
13997
+ if (unsupportedTargetKeys.length) {
13998
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint target only accepts uid, pageSchemaUid, tabSchemaUid or routeId`);
13999
+ }
14000
+ if (!Object.keys(target).length) {
14001
+ (0, import_errors.throwBadRequest)(
14002
+ `flowSurfaces exportBlueprint target requires one of uid, pageSchemaUid, tabSchemaUid or routeId`
14003
+ );
14004
+ }
14005
+ if (Object.keys(target).length > 1) {
14006
+ (0, import_errors.throwBadRequest)(
14007
+ `flowSurfaces exportBlueprint target only accepts exactly one locator: uid, pageSchemaUid, tabSchemaUid or routeId`
14008
+ );
14009
+ }
14010
+ if (target.tabSchemaUid) {
14011
+ (0, import_errors.throwBadRequest)(FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE);
14012
+ }
14013
+ return {
14014
+ target,
14015
+ unsupportedPolicy: this.normalizeExportBlueprintUnsupportedPolicy(input.options)
14016
+ };
14017
+ }
14018
+ normalizeExportBlueprintUnsupportedPolicy(input) {
14019
+ if (import_lodash.default.isUndefined(input)) {
14020
+ return "error";
14021
+ }
14022
+ if (!import_lodash.default.isPlainObject(input)) {
14023
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint options must be an object`);
14024
+ }
14025
+ const options = input;
14026
+ const unsupportedKeys = Object.keys(options).filter((key) => key !== "unsupported");
14027
+ if (unsupportedKeys.length) {
14028
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint options only accepts unsupported`);
14029
+ }
14030
+ const policy = options.unsupported;
14031
+ if (import_lodash.default.isUndefined(policy)) {
14032
+ return "error";
14033
+ }
14034
+ if (policy === "error" || policy === "warn") {
14035
+ return policy;
14036
+ }
14037
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint options.unsupported must be 'error' or 'warn'`);
14038
+ }
14039
+ normalizeExportBlueprintLocatorValue(value, key) {
14040
+ if (import_lodash.default.isNil(value)) {
14041
+ return void 0;
14042
+ }
14043
+ if (typeof value !== "string" && typeof value !== "number") {
14044
+ (0, import_errors.throwBadRequest)(`flowSurfaces exportBlueprint target.${key} must be a string`);
14045
+ }
14046
+ const normalized = String(value).trim();
14047
+ return normalized || void 0;
14048
+ }
14049
+ readRouteString(route, key) {
14050
+ var _a;
14051
+ const routeRecord = route;
14052
+ const value = ((_a = routeRecord == null ? void 0 : routeRecord.get) == null ? void 0 : _a.call(routeRecord, key)) ?? (routeRecord == null ? void 0 : routeRecord[key]);
14053
+ const normalized = typeof value === "string" ? value.trim() : "";
14054
+ return normalized || void 0;
14055
+ }
14056
+ resolveExportBlueprintPageSchemaUid(target, resolved) {
14057
+ const pageSchemaUid = this.readRouteString(resolved.pageRoute, "schemaUid") || (target.pageSchemaUid ? String(target.pageSchemaUid).trim() : "");
14058
+ if (!pageSchemaUid) {
14059
+ (0, import_errors.throwBadRequest)(FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE);
14060
+ }
14061
+ return pageSchemaUid;
14062
+ }
14063
+ async assertExportBlueprintRootTarget(target, resolved, pageSchemaUid, transaction) {
14064
+ const targetUid = target.uid ? String(target.uid).trim() : "";
14065
+ if (!targetUid) {
14066
+ return;
14067
+ }
14068
+ if (targetUid === pageSchemaUid) {
14069
+ return;
14070
+ }
14071
+ const rootPageModel = await this.repository.findModelByParentId(pageSchemaUid, {
14072
+ transaction,
14073
+ subKey: "page",
14074
+ includeAsyncNode: false
14075
+ });
14076
+ if ((rootPageModel == null ? void 0 : rootPageModel.uid) && targetUid === String(rootPageModel.uid).trim()) {
14077
+ return;
14078
+ }
14079
+ (0, import_errors.throwBadRequest)(FLOW_SURFACE_EXPORT_BLUEPRINT_ROOT_ONLY_MESSAGE);
14080
+ }
13697
14081
  normalizeContextPath(path) {
13698
14082
  if (import_lodash.default.isUndefined(path) || import_lodash.default.isNull(path)) {
13699
14083
  return void 0;
@@ -16860,13 +17244,20 @@ class FlowSurfacesService {
16860
17244
  description: changes.description,
16861
17245
  className: changes.className
16862
17246
  }),
16863
- stepParams: (0, import_service_utils.hasDefinedValue)(changes, ["code", "version"]) ? {
16864
- jsSettings: {
16865
- runJs: (0, import_service_utils.buildDefinedPayload)({
16866
- code: changes.code,
16867
- version: changes.version
16868
- })
16869
- }
17247
+ stepParams: (0, import_service_utils.hasDefinedValue)(changes, ["code", "version", "showBlockCard"]) ? {
17248
+ jsSettings: (0, import_service_utils.buildDefinedPayload)({
17249
+ ...(0, import_service_utils.hasDefinedValue)(changes, ["code", "version"]) ? {
17250
+ runJs: (0, import_service_utils.buildDefinedPayload)({
17251
+ code: changes.code,
17252
+ version: changes.version
17253
+ })
17254
+ } : {},
17255
+ ...(0, import_service_utils.hasOwnDefined)(changes, "showBlockCard") ? {
17256
+ showBlockCard: {
17257
+ showBlockCard: changes.showBlockCard
17258
+ }
17259
+ } : {}
17260
+ })
16870
17261
  } : void 0
16871
17262
  },
16872
17263
  options
@@ -17448,19 +17839,21 @@ class FlowSurfacesService {
17448
17839
  }
17449
17840
  return JSON.stringify(value);
17450
17841
  }
17451
- buildAIEmployeeActionDedupIdentity(values) {
17842
+ buildAIEmployeeActionDedupIdentity(values, defaultActionWorkContext) {
17452
17843
  var _a, _b, _c, _d, _e, _f;
17453
17844
  const username = String(((_b = (_a = values == null ? void 0 : values.props) == null ? void 0 : _a.aiEmployee) == null ? void 0 : _b.username) || "").trim();
17454
17845
  if (!username) {
17455
17846
  return "";
17456
17847
  }
17848
+ const workContext = this.normalizeAIEmployeeActionWorkContextForDedupIdentity(
17849
+ (_d = (_c = values == null ? void 0 : values.props) == null ? void 0 : _c.context) == null ? void 0 : _d.workContext,
17850
+ defaultActionWorkContext
17851
+ );
17457
17852
  return this.stableSerializeAIEmployeeValue({
17458
17853
  username,
17459
- auto: typeof ((_c = values == null ? void 0 : values.props) == null ? void 0 : _c.auto) === "boolean" ? values.props.auto : false,
17460
- workContext: this.normalizeAIEmployeeWorkContextForDedupIdentity((_e = (_d = values == null ? void 0 : values.props) == null ? void 0 : _d.context) == null ? void 0 : _e.workContext),
17461
- tasks: this.normalizeAIEmployeeTasksForDedupIdentity(
17462
- import_lodash.default.get(values, ["stepParams", ...AI_EMPLOYEE_TASK_STEP_PARAMS_PATH])
17463
- ),
17854
+ auto: typeof ((_e = values == null ? void 0 : values.props) == null ? void 0 : _e.auto) === "boolean" ? values.props.auto : false,
17855
+ workContext,
17856
+ tasks: this.normalizeAIEmployeeTasksForDedupIdentity(this.readAIEmployeePersistedTasks(values), workContext),
17464
17857
  style: {
17465
17858
  ...AI_EMPLOYEE_DEFAULT_STYLE,
17466
17859
  ...import_lodash.default.isPlainObject((_f = values == null ? void 0 : values.props) == null ? void 0 : _f.style) ? import_lodash.default.pick(values.props.style, AI_EMPLOYEE_STYLE_PUBLIC_KEYS) : {}
@@ -17468,11 +17861,35 @@ class FlowSurfacesService {
17468
17861
  });
17469
17862
  }
17470
17863
  normalizeAIEmployeeWorkContextForDedupIdentity(value) {
17471
- return import_lodash.default.castArray(value || []).map(
17472
- (item) => import_lodash.default.isPlainObject(item) ? import_lodash.default.pick(item, AI_EMPLOYEE_WORK_CONTEXT_PUBLIC_KEYS) : item
17473
- );
17864
+ return import_lodash.default.castArray(value || []).map((item) => {
17865
+ if (!import_lodash.default.isPlainObject(item)) {
17866
+ return item;
17867
+ }
17868
+ const output = import_lodash.default.pick(item, AI_EMPLOYEE_WORK_CONTEXT_PUBLIC_KEYS);
17869
+ if (!Object.prototype.hasOwnProperty.call(output, "type") || import_lodash.default.isUndefined(output.type) || output.type === null) {
17870
+ output.type = "flow-model";
17871
+ }
17872
+ return output;
17873
+ });
17874
+ }
17875
+ normalizeAIEmployeeActionWorkContextForDedupIdentity(value, defaultWorkContext) {
17876
+ if (!Array.isArray(value)) {
17877
+ return import_lodash.default.cloneDeep(defaultWorkContext || []);
17878
+ }
17879
+ return this.normalizeAIEmployeeWorkContextForDedupIdentity(value);
17880
+ }
17881
+ normalizeAIEmployeeDefaultActionWorkContextForSelfUid(selfUid) {
17882
+ const uid2 = String(selfUid || "").trim();
17883
+ return uid2 ? [{ type: "flow-model", uid: uid2 }] : [];
17474
17884
  }
17475
- normalizeAIEmployeeTasksForDedupIdentity(value) {
17885
+ normalizeAIEmployeeTaskWorkContextForDedupIdentity(value, defaultWorkContext) {
17886
+ const normalized = this.normalizeAIEmployeeWorkContextForDedupIdentity(value);
17887
+ if (Array.isArray(defaultWorkContext) && !normalized.length) {
17888
+ return import_lodash.default.cloneDeep(defaultWorkContext);
17889
+ }
17890
+ return normalized;
17891
+ }
17892
+ normalizeAIEmployeeTasksForDedupIdentity(value, defaultWorkContext) {
17476
17893
  return import_lodash.default.castArray(value || []).map((task) => {
17477
17894
  if (!import_lodash.default.isPlainObject(task)) {
17478
17895
  return task;
@@ -17481,9 +17898,19 @@ class FlowSurfacesService {
17481
17898
  if (import_lodash.default.isPlainObject(output.message)) {
17482
17899
  output.message = import_lodash.default.pick(output.message, AI_EMPLOYEE_TASK_MESSAGE_PUBLIC_KEYS);
17483
17900
  if (Object.prototype.hasOwnProperty.call(output.message, "workContext")) {
17484
- output.message.workContext = this.normalizeAIEmployeeWorkContextForDedupIdentity(output.message.workContext);
17901
+ output.message.workContext = this.normalizeAIEmployeeTaskWorkContextForDedupIdentity(
17902
+ output.message.workContext,
17903
+ defaultWorkContext
17904
+ );
17485
17905
  }
17486
17906
  }
17907
+ if (!import_lodash.default.isPlainObject(output.message) && Array.isArray(defaultWorkContext)) {
17908
+ output.message = {
17909
+ workContext: import_lodash.default.cloneDeep(defaultWorkContext)
17910
+ };
17911
+ } else if (import_lodash.default.isPlainObject(output.message) && !Object.prototype.hasOwnProperty.call(output.message, "workContext")) {
17912
+ output.message.workContext = import_lodash.default.cloneDeep(defaultWorkContext || []);
17913
+ }
17487
17914
  if (import_lodash.default.isPlainObject(output.model)) {
17488
17915
  output.model = import_lodash.default.pick(output.model, AI_EMPLOYEE_TASK_MODEL_PUBLIC_KEYS);
17489
17916
  }
@@ -17493,25 +17920,38 @@ class FlowSurfacesService {
17493
17920
  return output;
17494
17921
  });
17495
17922
  }
17496
- async assertNoDuplicateAIEmployeeAction(actionName, parentUid, values, transaction) {
17923
+ async assertNoDuplicateAIEmployeeAction(actionName, parentUid, values, transaction, excludeUid) {
17497
17924
  var _a;
17498
- const identity = this.buildAIEmployeeActionDedupIdentity(values);
17499
- if (!identity) {
17500
- return;
17501
- }
17502
17925
  const parentNode = await this.repository.findModelById(parentUid, {
17503
17926
  transaction,
17504
17927
  includeAsyncNode: true
17505
17928
  });
17506
- const duplicate = import_lodash.default.castArray(((_a = parentNode == null ? void 0 : parentNode.subModels) == null ? void 0 : _a.actions) || []).find((action) => {
17929
+ const defaultActionWorkContext = this.normalizeAIEmployeeDefaultActionWorkContextForSelfUid(
17930
+ await this.resolveAIEmployeeActionSelfUidFromParentNode(parentNode, transaction)
17931
+ );
17932
+ const identity = this.buildAIEmployeeActionDedupIdentity(values, defaultActionWorkContext);
17933
+ if (!identity) {
17934
+ return;
17935
+ }
17936
+ let duplicate;
17937
+ for (const action of import_lodash.default.castArray(((_a = parentNode == null ? void 0 : parentNode.subModels) == null ? void 0 : _a.actions) || [])) {
17507
17938
  if (!this.isAIEmployeeActionUse(action == null ? void 0 : action.use)) {
17508
- return false;
17939
+ continue;
17509
17940
  }
17510
- return this.buildAIEmployeeActionDedupIdentity({
17511
- props: action.props,
17512
- stepParams: action.stepParams
17513
- }) === identity;
17514
- });
17941
+ if (excludeUid && String((action == null ? void 0 : action.uid) || "") === excludeUid) {
17942
+ continue;
17943
+ }
17944
+ if (this.buildAIEmployeeActionDedupIdentity(
17945
+ {
17946
+ props: action.props,
17947
+ stepParams: action.stepParams
17948
+ },
17949
+ defaultActionWorkContext
17950
+ ) === identity) {
17951
+ duplicate = action;
17952
+ break;
17953
+ }
17954
+ }
17515
17955
  if (!(duplicate == null ? void 0 : duplicate.uid)) {
17516
17956
  return;
17517
17957
  }
@@ -17526,6 +17966,25 @@ class FlowSurfacesService {
17526
17966
  }
17527
17967
  );
17528
17968
  }
17969
+ async assertNoDuplicateAIEmployeeActionForUpdateSettings(actionName, current, effectiveNode, transaction) {
17970
+ if (!this.isAIEmployeeActionUse(current == null ? void 0 : current.use)) {
17971
+ return;
17972
+ }
17973
+ const parentUid = String((current == null ? void 0 : current.parentId) || "").trim() || ((current == null ? void 0 : current.uid) ? await this.locator.findParentUid(current.uid, transaction).catch(() => "") : "");
17974
+ if (!parentUid) {
17975
+ return;
17976
+ }
17977
+ await this.assertNoDuplicateAIEmployeeAction(
17978
+ actionName,
17979
+ parentUid,
17980
+ {
17981
+ props: effectiveNode == null ? void 0 : effectiveNode.props,
17982
+ stepParams: effectiveNode == null ? void 0 : effectiveNode.stepParams
17983
+ },
17984
+ transaction,
17985
+ String((current == null ? void 0 : current.uid) || "")
17986
+ );
17987
+ }
17529
17988
  hasAIEmployeePublicSettings(settings) {
17530
17989
  return import_lodash.default.isPlainObject(settings) && AI_EMPLOYEE_PUBLIC_SETTING_KEYS.some((key) => Object.prototype.hasOwnProperty.call(settings, key));
17531
17990
  }
@@ -17580,11 +18039,24 @@ class FlowSurfacesService {
17580
18039
  var _a;
17581
18040
  const stepTasks = import_lodash.default.get(current, ["stepParams", ...AI_EMPLOYEE_TASK_STEP_PARAMS_PATH]);
17582
18041
  if (Array.isArray(stepTasks)) {
17583
- return stepTasks;
18042
+ return this.normalizeAIEmployeeLegacyInheritedTaskWorkContext(stepTasks);
17584
18043
  }
17585
- const legacyPropsTasks = (_a = current == null ? void 0 : current.props) == null ? void 0 : _a.tasks;
18044
+ const legacyPropsTasks = this.normalizeAIEmployeeLegacyInheritedTaskWorkContext((_a = current == null ? void 0 : current.props) == null ? void 0 : _a.tasks);
17586
18045
  return Array.isArray(legacyPropsTasks) ? legacyPropsTasks : [];
17587
18046
  }
18047
+ normalizeAIEmployeeLegacyInheritedTaskWorkContext(tasks) {
18048
+ if (!Array.isArray(tasks)) {
18049
+ return tasks;
18050
+ }
18051
+ return tasks.map((task) => {
18052
+ if (!import_lodash.default.isPlainObject(task) || !import_lodash.default.isPlainObject(task.message) || task.message.workContext !== null) {
18053
+ return task;
18054
+ }
18055
+ const nextTask = import_lodash.default.cloneDeep(task);
18056
+ delete nextTask.message.workContext;
18057
+ return nextTask;
18058
+ });
18059
+ }
17588
18060
  buildAIEmployeeTaskStepParams(tasks) {
17589
18061
  const stepParams = {};
17590
18062
  import_lodash.default.set(stepParams, AI_EMPLOYEE_TASK_STEP_PARAMS_PATH, import_lodash.default.cloneDeep(tasks));
@@ -17613,7 +18085,7 @@ class FlowSurfacesService {
17613
18085
  if (!this.isAIEmployeeActionUse(current == null ? void 0 : current.use)) {
17614
18086
  return;
17615
18087
  }
17616
- const legacyPropsTasks = (_a = current == null ? void 0 : current.props) == null ? void 0 : _a.tasks;
18088
+ const legacyPropsTasks = this.normalizeAIEmployeeLegacyInheritedTaskWorkContext((_a = current == null ? void 0 : current.props) == null ? void 0 : _a.tasks);
17617
18089
  const hasLegacyPropsTasks = Array.isArray(legacyPropsTasks);
17618
18090
  const hasNextStepTasks = import_lodash.default.has(nextPayload, ["stepParams", ...AI_EMPLOYEE_TASK_STEP_PARAMS_PATH]);
17619
18091
  const currentStepTasks = import_lodash.default.get(current, ["stepParams", ...AI_EMPLOYEE_TASK_STEP_PARAMS_PATH]);
@@ -17785,6 +18257,20 @@ class FlowSurfacesService {
17785
18257
  };
17786
18258
  });
17787
18259
  }
18260
+ normalizeAIEmployeeEffectiveActionWorkContext(actionName, settings, currentProps, options) {
18261
+ var _a;
18262
+ const hasSettingsWorkContext = Object.prototype.hasOwnProperty.call(settings, "workContext");
18263
+ const currentWorkContext = (_a = currentProps == null ? void 0 : currentProps.context) == null ? void 0 : _a.workContext;
18264
+ if (!hasSettingsWorkContext && !Array.isArray(currentWorkContext) && !options.requireUsername && !options.selfUid) {
18265
+ return void 0;
18266
+ }
18267
+ const rawWorkContext = hasSettingsWorkContext ? settings.workContext : Array.isArray(currentWorkContext) ? currentWorkContext : [{ type: "flow-model", target: "self" }];
18268
+ return this.normalizeAIEmployeeWorkContext(actionName, rawWorkContext, {
18269
+ selfUid: options.selfUid,
18270
+ keyMap: options.keyMap,
18271
+ path: "settings.workContext"
18272
+ });
18273
+ }
17788
18274
  normalizeAIEmployeeTaskModel(actionName, path, value) {
17789
18275
  if (import_lodash.default.isUndefined(value) || value === null) {
17790
18276
  return value;
@@ -18100,6 +18586,7 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18100
18586
  );
18101
18587
  }
18102
18588
  async normalizeAIEmployeeStepParamTasksForUpdateSettings(current, nextPayload, writeTarget, options) {
18589
+ var _a, _b, _c, _d;
18103
18590
  if (!this.isAIEmployeeActionUse(current == null ? void 0 : current.use) || !import_lodash.default.has(nextPayload, ["stepParams", ...AI_EMPLOYEE_TASK_STEP_PARAMS_PATH])) {
18104
18591
  return;
18105
18592
  }
@@ -18108,15 +18595,63 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18108
18595
  return;
18109
18596
  }
18110
18597
  const actionName = options.openViewActionName || "updateSettings";
18111
- const normalizedTasks = this.normalizeAIEmployeeTasks(
18598
+ const selfUid = await this.resolveAIEmployeeActionSelfUid(current || { uid: writeTarget.uid }, options.transaction);
18599
+ const currentPropsForDefault = import_lodash.default.mergeWith(
18600
+ {},
18601
+ import_lodash.default.isPlainObject(current == null ? void 0 : current.props) ? current.props : {},
18602
+ import_lodash.default.isPlainObject(nextPayload.props) ? nextPayload.props : {},
18603
+ (_currentValue, nextValue) => {
18604
+ if (Array.isArray(nextValue)) {
18605
+ return import_lodash.default.cloneDeep(nextValue);
18606
+ }
18607
+ return void 0;
18608
+ }
18609
+ );
18610
+ const defaultWorkContext = this.normalizeAIEmployeeEffectiveActionWorkContext(
18112
18611
  actionName,
18113
- tasks,
18114
- this.readAIEmployeePersistedTasks(current),
18612
+ {},
18613
+ currentPropsForDefault,
18115
18614
  {
18116
- selfUid: await this.resolveAIEmployeeActionSelfUid(current || { uid: writeTarget.uid }, options.transaction),
18117
- path: "stepParams.shortcutSettings.editTasks.tasks"
18615
+ selfUid,
18616
+ requireUsername: true
18118
18617
  }
18119
18618
  );
18619
+ const currentTasks = this.readAIEmployeePersistedTasks(current);
18620
+ const previousActionWorkContext = this.normalizeAIEmployeeActionWorkContextForDedupIdentity(
18621
+ (_b = (_a = current == null ? void 0 : current.props) == null ? void 0 : _a.context) == null ? void 0 : _b.workContext,
18622
+ this.normalizeAIEmployeeDefaultActionWorkContextForSelfUid(selfUid)
18623
+ );
18624
+ const nextActionWorkContext = this.normalizeAIEmployeeActionWorkContextForDedupIdentity(
18625
+ (_c = currentPropsForDefault == null ? void 0 : currentPropsForDefault.context) == null ? void 0 : _c.workContext,
18626
+ defaultWorkContext
18627
+ );
18628
+ if (Array.isArray(defaultWorkContext) && !import_lodash.default.isEqual((_d = currentPropsForDefault == null ? void 0 : currentPropsForDefault.context) == null ? void 0 : _d.workContext, defaultWorkContext)) {
18629
+ nextPayload.props = import_lodash.default.mergeWith(
18630
+ {},
18631
+ currentPropsForDefault,
18632
+ {
18633
+ context: {
18634
+ workContext: import_lodash.default.cloneDeep(defaultWorkContext)
18635
+ }
18636
+ },
18637
+ (_currentValue, nextValue) => {
18638
+ if (Array.isArray(nextValue)) {
18639
+ return import_lodash.default.cloneDeep(nextValue);
18640
+ }
18641
+ return void 0;
18642
+ }
18643
+ );
18644
+ }
18645
+ const currentTasksForNormalization = this.rebaseAIEmployeeInheritedTaskWorkContext(
18646
+ currentTasks,
18647
+ previousActionWorkContext,
18648
+ nextActionWorkContext
18649
+ );
18650
+ const normalizedTasks = this.normalizeAIEmployeeTasks(actionName, tasks, currentTasksForNormalization, {
18651
+ selfUid,
18652
+ defaultWorkContext,
18653
+ path: "stepParams.shortcutSettings.editTasks.tasks"
18654
+ });
18120
18655
  import_lodash.default.set(nextPayload, ["stepParams", ...AI_EMPLOYEE_TASK_STEP_PARAMS_PATH], normalizedTasks);
18121
18656
  }
18122
18657
  normalizeAIEmployeeTaskMessage(actionName, path, value, existing, options) {
@@ -18145,13 +18680,18 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18145
18680
  if (Object.prototype.hasOwnProperty.call(nextMessage, "user") && typeof nextMessage.user !== "string") {
18146
18681
  (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} ${path}.user must be a string`);
18147
18682
  }
18148
- if (Object.prototype.hasOwnProperty.call(value, "workContext")) {
18683
+ if (value.workContext === null) {
18684
+ delete nextMessage.workContext;
18685
+ } else if (Object.prototype.hasOwnProperty.call(value, "workContext")) {
18149
18686
  nextMessage.workContext = this.normalizeAIEmployeeWorkContext(actionName, value.workContext, {
18150
18687
  selfUid: options.selfUid,
18151
18688
  keyMap: options.keyMap,
18152
18689
  path: `${path}.workContext`
18153
18690
  });
18154
18691
  }
18692
+ if (!Object.prototype.hasOwnProperty.call(nextMessage, "workContext") && this.shouldMaterializeAIEmployeeTaskDefaultWorkContext(options.defaultWorkContext)) {
18693
+ nextMessage.workContext = import_lodash.default.cloneDeep(options.defaultWorkContext);
18694
+ }
18155
18695
  return nextMessage;
18156
18696
  }
18157
18697
  normalizeAIEmployeeTaskPatch(actionName, patch, existing, options) {
@@ -18175,7 +18715,8 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18175
18715
  if (key === "message") {
18176
18716
  next.message = this.normalizeAIEmployeeTaskMessage(actionName, `${options.path}.message`, value, next.message, {
18177
18717
  selfUid: options.selfUid,
18178
- keyMap: options.keyMap
18718
+ keyMap: options.keyMap,
18719
+ defaultWorkContext: options.defaultWorkContext
18179
18720
  });
18180
18721
  return;
18181
18722
  }
@@ -18225,6 +18766,9 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18225
18766
  if (!import_lodash.default.isPlainObject(next.message)) {
18226
18767
  next.message = {};
18227
18768
  }
18769
+ if (!Object.prototype.hasOwnProperty.call(next.message, "workContext") && this.shouldMaterializeAIEmployeeTaskDefaultWorkContext(options.defaultWorkContext)) {
18770
+ next.message.workContext = import_lodash.default.cloneDeep(options.defaultWorkContext);
18771
+ }
18228
18772
  if (import_lodash.default.isPlainObject(next.skillSettings)) {
18229
18773
  if (Array.isArray(next.skillSettings.skills) && !Object.prototype.hasOwnProperty.call(next.skillSettings, "skillsVersion")) {
18230
18774
  next.skillSettings.skillsVersion = 2;
@@ -18251,10 +18795,52 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18251
18795
  nextTasks[index] = this.normalizeAIEmployeeTaskPatch(actionName, task, existingTasks[index], {
18252
18796
  selfUid: options.selfUid,
18253
18797
  keyMap: options.keyMap,
18254
- path: `${options.path}[${index}]`
18798
+ path: `${options.path}[${index}]`,
18799
+ defaultWorkContext: options.defaultWorkContext
18255
18800
  });
18256
18801
  });
18257
- return nextTasks;
18802
+ return this.withAIEmployeeTaskDefaultWorkContext(nextTasks, options.defaultWorkContext);
18803
+ }
18804
+ withAIEmployeeTaskDefaultWorkContext(tasks, defaultWorkContext) {
18805
+ const nextTasks = Array.isArray(tasks) ? import_lodash.default.cloneDeep(tasks) : [];
18806
+ if (!this.shouldMaterializeAIEmployeeTaskDefaultWorkContext(defaultWorkContext)) {
18807
+ return nextTasks;
18808
+ }
18809
+ return nextTasks.map((task) => {
18810
+ if (!import_lodash.default.isPlainObject(task)) {
18811
+ return task;
18812
+ }
18813
+ const nextTask = import_lodash.default.cloneDeep(task);
18814
+ if (!import_lodash.default.isPlainObject(nextTask.message)) {
18815
+ nextTask.message = {
18816
+ workContext: import_lodash.default.cloneDeep(defaultWorkContext)
18817
+ };
18818
+ } else if (!Object.prototype.hasOwnProperty.call(nextTask.message, "workContext")) {
18819
+ nextTask.message.workContext = import_lodash.default.cloneDeep(defaultWorkContext);
18820
+ }
18821
+ return nextTask;
18822
+ });
18823
+ }
18824
+ shouldMaterializeAIEmployeeTaskDefaultWorkContext(defaultWorkContext) {
18825
+ return Array.isArray(defaultWorkContext) && defaultWorkContext.length > 0;
18826
+ }
18827
+ rebaseAIEmployeeInheritedTaskWorkContext(currentTasks, previousActionWorkContext, nextActionWorkContext) {
18828
+ const tasks = this.normalizeAIEmployeeLegacyInheritedTaskWorkContext(currentTasks) || [];
18829
+ if (!previousActionWorkContext.length || import_lodash.default.isEqual(previousActionWorkContext, nextActionWorkContext)) {
18830
+ return tasks;
18831
+ }
18832
+ return tasks.map((task) => {
18833
+ const nextTask = import_lodash.default.cloneDeep(task);
18834
+ if (import_lodash.default.isPlainObject(nextTask == null ? void 0 : nextTask.message)) {
18835
+ const currentTaskWorkContext = this.normalizeAIEmployeeWorkContextForDedupIdentity(
18836
+ nextTask.message.workContext
18837
+ );
18838
+ if (import_lodash.default.isEqual(currentTaskWorkContext, previousActionWorkContext)) {
18839
+ delete nextTask.message.workContext;
18840
+ }
18841
+ }
18842
+ return nextTask;
18843
+ });
18258
18844
  }
18259
18845
  normalizeAIEmployeeActionSettingsReferences(actionName, settings, options) {
18260
18846
  if (!this.hasAIEmployeePublicSettings(settings)) {
@@ -18268,15 +18854,22 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18268
18854
  });
18269
18855
  }
18270
18856
  if (Object.prototype.hasOwnProperty.call(nextSettings, "tasks")) {
18857
+ const defaultWorkContext = this.normalizeAIEmployeeEffectiveActionWorkContext(
18858
+ actionName,
18859
+ nextSettings,
18860
+ {},
18861
+ options
18862
+ );
18271
18863
  nextSettings.tasks = this.normalizeAIEmployeeTasks(actionName, nextSettings.tasks, [], {
18272
18864
  ...options,
18273
- path: "settings.tasks"
18865
+ path: "settings.tasks",
18866
+ defaultWorkContext
18274
18867
  });
18275
18868
  }
18276
18869
  return nextSettings;
18277
18870
  }
18278
18871
  async normalizeAIEmployeeActionPublicSettings(actionName, settings, options) {
18279
- var _a, _b;
18872
+ var _a, _b, _c, _d;
18280
18873
  this.assertAIEmployeePluginEnabled(actionName, options.enabledPackages);
18281
18874
  if (!import_lodash.default.isPlainObject(settings)) {
18282
18875
  (0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} AI employee settings must be an object`);
@@ -18296,6 +18889,17 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18296
18889
  }
18297
18890
  const props = {};
18298
18891
  const stepParams = {};
18892
+ const effectiveActionWorkContext = this.normalizeAIEmployeeEffectiveActionWorkContext(
18893
+ actionName,
18894
+ settings,
18895
+ currentProps,
18896
+ options
18897
+ );
18898
+ const previousActionWorkContext = this.normalizeAIEmployeeActionWorkContextForDedupIdentity(
18899
+ (_c = currentProps == null ? void 0 : currentProps.context) == null ? void 0 : _c.workContext,
18900
+ this.normalizeAIEmployeeDefaultActionWorkContextForSelfUid(options.selfUid)
18901
+ );
18902
+ const nextActionWorkContext = this.normalizeAIEmployeeWorkContextForDedupIdentity(effectiveActionWorkContext);
18299
18903
  if (effectiveUsername && (hasUsername || options.requireUsername)) {
18300
18904
  props.aiEmployee = {
18301
18905
  ...import_lodash.default.isPlainObject(currentProps.aiEmployee) ? import_lodash.default.cloneDeep(currentProps.aiEmployee) : {},
@@ -18309,28 +18913,25 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18309
18913
  }
18310
18914
  props.auto = auto;
18311
18915
  }
18312
- if (Object.prototype.hasOwnProperty.call(settings, "workContext") || options.requireUsername) {
18313
- const rawWorkContext = Object.prototype.hasOwnProperty.call(settings, "workContext") ? settings.workContext : [{ type: "flow-model", target: "self" }];
18916
+ if (Array.isArray(effectiveActionWorkContext) && (Object.prototype.hasOwnProperty.call(settings, "workContext") || options.requireUsername || !import_lodash.default.isEqual((_d = currentProps == null ? void 0 : currentProps.context) == null ? void 0 : _d.workContext, effectiveActionWorkContext))) {
18314
18917
  props.context = {
18315
18918
  ...import_lodash.default.isPlainObject(currentProps.context) ? import_lodash.default.cloneDeep(currentProps.context) : {},
18316
- workContext: this.normalizeAIEmployeeWorkContext(actionName, rawWorkContext, {
18317
- selfUid: options.selfUid,
18318
- keyMap: options.keyMap,
18319
- path: "settings.workContext"
18320
- })
18919
+ workContext: import_lodash.default.cloneDeep(effectiveActionWorkContext)
18321
18920
  };
18322
18921
  }
18323
18922
  if (Object.prototype.hasOwnProperty.call(settings, "tasks")) {
18324
- const normalizedTasks = this.normalizeAIEmployeeTasks(
18325
- actionName,
18326
- settings.tasks,
18327
- this.readAIEmployeePersistedTasks(options.current),
18328
- {
18329
- selfUid: options.selfUid,
18330
- keyMap: options.keyMap,
18331
- path: "settings.tasks"
18332
- }
18923
+ const currentTasks = this.readAIEmployeePersistedTasks(options.current);
18924
+ const currentTasksForNormalization = this.rebaseAIEmployeeInheritedTaskWorkContext(
18925
+ currentTasks,
18926
+ previousActionWorkContext,
18927
+ nextActionWorkContext
18333
18928
  );
18929
+ const normalizedTasks = this.normalizeAIEmployeeTasks(actionName, settings.tasks, currentTasksForNormalization, {
18930
+ selfUid: options.selfUid,
18931
+ keyMap: options.keyMap,
18932
+ path: "settings.tasks",
18933
+ defaultWorkContext: effectiveActionWorkContext
18934
+ });
18334
18935
  const validation = options.promptContext && normalizedTasks.length ? await this.buildAIEmployeePromptValidationContext(
18335
18936
  actionName,
18336
18937
  [
@@ -18351,6 +18952,17 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18351
18952
  const tasks = this.appendAIEmployeeCurrentRecordPromptVariableToTasks(normalizedTasks, validation);
18352
18953
  this.assertAIEmployeeTaskPromptVariablesAllowed(actionName, tasks, validation);
18353
18954
  import_lodash.default.merge(stepParams, this.buildAIEmployeeTaskStepParams(tasks));
18955
+ } else if (!options.skipExistingTaskWorkContextRebase && Object.prototype.hasOwnProperty.call(settings, "workContext") && !import_lodash.default.isEqual(previousActionWorkContext, nextActionWorkContext)) {
18956
+ const currentTasks = this.readAIEmployeePersistedTasks(options.current);
18957
+ const rebasedTasks = this.rebaseAIEmployeeInheritedTaskWorkContext(
18958
+ currentTasks,
18959
+ previousActionWorkContext,
18960
+ nextActionWorkContext
18961
+ );
18962
+ const tasks = this.withAIEmployeeTaskDefaultWorkContext(rebasedTasks, effectiveActionWorkContext);
18963
+ if (tasks.length) {
18964
+ import_lodash.default.merge(stepParams, this.buildAIEmployeeTaskStepParams(tasks));
18965
+ }
18354
18966
  }
18355
18967
  if (Object.prototype.hasOwnProperty.call(settings, "style") || options.requireUsername) {
18356
18968
  const style = Object.prototype.hasOwnProperty.call(settings, "style") ? settings.style : {};
@@ -18392,7 +19004,16 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18392
19004
  transaction,
18393
19005
  includeAsyncNode: true
18394
19006
  });
18395
- if (["TableActionsColumnModel", "ListItemModel", "GridCardItemModel"].includes(String((parentNode == null ? void 0 : parentNode.use) || ""))) {
19007
+ return await this.resolveAIEmployeeActionSelfUidFromParentNode(parentNode, transaction) || parentUid;
19008
+ }
19009
+ async resolveAIEmployeeActionSelfUidFromParentNode(parentNode, transaction) {
19010
+ const parentUid = String((parentNode == null ? void 0 : parentNode.uid) || "").trim();
19011
+ if (!parentUid) {
19012
+ return "";
19013
+ }
19014
+ if (["TableActionsColumnModel", "ListItemModel", "GridCardItemModel", "CommentItemModel"].includes(
19015
+ String((parentNode == null ? void 0 : parentNode.use) || "")
19016
+ )) {
18396
19017
  const ownerUid = String((parentNode == null ? void 0 : parentNode.parentId) || "").trim() || ((parentNode == null ? void 0 : parentNode.uid) ? await this.locator.findParentUid(parentNode.uid, transaction).catch(() => "") : "");
18397
19018
  return ownerUid || parentUid;
18398
19019
  }
@@ -18441,13 +19062,14 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18441
19062
  }
18442
19063
  const normalizedDefaultFilter = (0, import_service_utils.hasOwnDefined)(changes, "defaultFilter") ? this.normalizeFilterActionDefaultFilterValue(changes.defaultFilter) : void 0;
18443
19064
  const stepParams = {};
18444
- if ((0, import_service_utils.hasDefinedValue)(changes, ["title", "tooltip", "icon", "type", "danger", "color", "linkageRules"])) {
19065
+ if ((0, import_service_utils.hasDefinedValue)(changes, ["title", "tooltip", "icon", "iconOnly", "type", "danger", "color", "linkageRules"])) {
18445
19066
  stepParams.buttonSettings = {
18446
- ...(0, import_service_utils.hasDefinedValue)(changes, ["title", "tooltip", "icon", "type", "danger", "color"]) ? {
19067
+ ...(0, import_service_utils.hasDefinedValue)(changes, ["title", "tooltip", "icon", "iconOnly", "type", "danger", "color"]) ? {
18447
19068
  general: (0, import_service_utils.buildDefinedPayload)({
18448
19069
  title: changes.title,
18449
19070
  tooltip: changes.tooltip,
18450
19071
  icon: changes.icon,
19072
+ iconOnly: changes.iconOnly,
18451
19073
  type: changes.type,
18452
19074
  danger: changes.danger,
18453
19075
  color: changes.color
@@ -18657,6 +19279,7 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18657
19279
  title: changes.title,
18658
19280
  tooltip: changes.tooltip,
18659
19281
  icon: changes.icon,
19282
+ iconOnly: changes.iconOnly,
18660
19283
  type: changes.type,
18661
19284
  htmlType: changes.htmlType,
18662
19285
  position: changes.position,
@@ -18786,6 +19409,11 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18786
19409
  useStrictOnly: input.useStrictOnly
18787
19410
  });
18788
19411
  }
19412
+ isCollectionTitleField(collection, fieldName) {
19413
+ const normalizedFieldName = String(fieldName || "").trim();
19414
+ const titleFieldName = String((0, import_service_helpers.getCollectionTitleFieldName)(collection) || "").trim();
19415
+ return !!normalizedFieldName && normalizedFieldName === titleFieldName;
19416
+ }
18789
19417
  resolveAssociationLeafDisplaySemantics(field, dataSourceKey, enabledPackages) {
18790
19418
  const registeredBinding = this.resolveRegisteredFieldBinding({
18791
19419
  containerUse: "DetailsItemModel",
@@ -18821,6 +19449,9 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18821
19449
  }
18822
19450
  buildFieldMenuDirectCandidates(input) {
18823
19451
  const collection = this.getCollection(input.resourceInit.dataSourceKey, input.resourceInit.collectionName);
19452
+ const explicitDefaultFieldPaths = (0, import_default_action_popup.collectFlowSurfaceDefaultActionPopupFieldGroupFieldPaths)(
19453
+ input.defaultFieldGroups
19454
+ );
18824
19455
  return (0, import_service_helpers.getCollectionFields)(collection).flatMap((field) => {
18825
19456
  var _a;
18826
19457
  const fieldName = (0, import_service_helpers.getFieldName)(field);
@@ -18831,6 +19462,9 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18831
19462
  if (input.generatedPopupOnly && !(0, import_default_action_popup.isFlowSurfaceDefaultActionPopupBusinessField)(field)) {
18832
19463
  return [];
18833
19464
  }
19465
+ if ((0, import_relation_backing_foreign_key.isRelationBackingForeignKeyField)(collection, field) && !explicitDefaultFieldPaths.has(fieldName)) {
19466
+ return [];
19467
+ }
18834
19468
  if (input.mode === "table" && ((_a = field == null ? void 0 : field.options) == null ? void 0 : _a.treeChildren)) {
18835
19469
  return [];
18836
19470
  }
@@ -18918,6 +19552,9 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
18918
19552
  if (!targetFieldName) {
18919
19553
  continue;
18920
19554
  }
19555
+ if ((0, import_relation_backing_foreign_key.isRelationBackingForeignKeyField)(targetCollection, targetField) && !this.isCollectionTitleField(targetCollection, targetFieldName)) {
19556
+ continue;
19557
+ }
18921
19558
  nextCandidates.push({
18922
19559
  field: targetField,
18923
19560
  fieldPath: `${associationPathName}.${targetFieldName}`,
@@ -19092,7 +19729,7 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
19092
19729
  const getFields = (targetCollection) => (0, import_service_helpers.getCollectionFields)(targetCollection);
19093
19730
  const isFilterFieldVisible = (field) => (0, import_service_helpers.getFieldFilterable)(field) !== false && !!(0, import_service_helpers.getFieldInterface)(field);
19094
19731
  const directFields = getFields(collection).filter(
19095
- (field) => ["FilterFormBlockModel", "FilterFormGridModel", "FilterFormItemModel"].includes(input.ownerUse) ? isFilterFieldVisible(field) : !!(0, import_service_helpers.getFieldInterface)(field)
19732
+ (field) => !(0, import_relation_backing_foreign_key.isRelationBackingForeignKeyField)(collection, field) && (["FilterFormBlockModel", "FilterFormGridModel", "FilterFormItemModel"].includes(input.ownerUse) ? isFilterFieldVisible(field) : !!(0, import_service_helpers.getFieldInterface)(field))
19096
19733
  );
19097
19734
  if (!directFields.length && !collection) {
19098
19735
  return [];
@@ -19106,9 +19743,13 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
19106
19743
  if (!(0, import_service_helpers.isAssociationField)(field) || !targetCollection) {
19107
19744
  return [];
19108
19745
  }
19109
- return getFields(targetCollection).filter(
19110
- (targetField) => ["FilterFormBlockModel", "FilterFormGridModel", "FilterFormItemModel"].includes(input.ownerUse) ? isFilterFieldVisible(targetField) : !!(0, import_service_helpers.getFieldInterface)(targetField)
19111
- ).map((targetField) => ({
19746
+ return getFields(targetCollection).filter((targetField) => {
19747
+ const targetFieldName = (0, import_service_helpers.getFieldName)(targetField);
19748
+ if ((0, import_relation_backing_foreign_key.isRelationBackingForeignKeyField)(targetCollection, targetField) && !this.isCollectionTitleField(targetCollection, targetFieldName)) {
19749
+ return false;
19750
+ }
19751
+ return ["FilterFormBlockModel", "FilterFormGridModel", "FilterFormItemModel"].includes(input.ownerUse) ? isFilterFieldVisible(targetField) : !!(0, import_service_helpers.getFieldInterface)(targetField);
19752
+ }).map((targetField) => ({
19112
19753
  field: targetField,
19113
19754
  fieldPath: `${(0, import_service_helpers.getFieldName)(field)}.${(0, import_service_helpers.getFieldName)(targetField)}`,
19114
19755
  associationPathName: (0, import_service_helpers.getFieldName)(field),