@sap/ux-specification 1.136.14 → 1.136.15

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 (174) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/documentation/v2/v2-AnalyticalListPage.html +2 -2
  3. package/dist/documentation/v2/v2-ApplicationV2.html +2 -2
  4. package/dist/documentation/v2/v2-ListReport.html +2 -2
  5. package/dist/documentation/v2/v2-ListReportNew.html +2 -2
  6. package/dist/documentation/v2/v2-ObjectPage.html +2 -2
  7. package/dist/documentation/v2/v2-OverviewPage.html +2 -2
  8. package/dist/documentation/v4/v4-ApplicationV4.html +2 -2
  9. package/dist/documentation/v4/v4-BuildingBlocks.html +2 -2
  10. package/dist/documentation/v4/v4-FreestylePage.html +2 -2
  11. package/dist/documentation/v4/v4-ListReport.html +2 -2
  12. package/dist/documentation/v4/v4-ObjectPage.html +2 -2
  13. package/dist/index-min.js +257 -258
  14. package/dist/index-min.js.map +4 -4
  15. package/dist/schemas/v4/BuildingBlocksConfig.json +72 -35
  16. package/dist/schemas/v4/ListReportConfig.json +251 -28
  17. package/dist/schemas/v4/ObjectPageConfig.json +385 -130
  18. package/dist/specification/package.json +8 -8
  19. package/dist/specification/scripts/macros/corrections.d.ts.map +1 -1
  20. package/dist/specification/scripts/macros/corrections.js +17 -1
  21. package/dist/specification/scripts/macros/corrections.js.map +1 -1
  22. package/dist/specification/scripts/macros/schema.d.ts.map +1 -1
  23. package/dist/specification/scripts/macros/schema.js +10 -1
  24. package/dist/specification/scripts/macros/schema.js.map +1 -1
  25. package/dist/specification/scripts/macros/types.d.ts +1 -0
  26. package/dist/specification/scripts/macros/types.d.ts.map +1 -1
  27. package/dist/specification/src/api.d.ts.map +1 -1
  28. package/dist/specification/src/api.js +2 -1
  29. package/dist/specification/src/api.js.map +1 -1
  30. package/dist/specification/src/sync/common/DataFieldStrategy.d.ts +38 -8
  31. package/dist/specification/src/sync/common/DataFieldStrategy.d.ts.map +1 -1
  32. package/dist/specification/src/sync/common/DataFieldStrategy.js +64 -11
  33. package/dist/specification/src/sync/common/DataFieldStrategy.js.map +1 -1
  34. package/dist/specification/src/sync/common/ManifestDrivenSchemaProcessor.d.ts +0 -4
  35. package/dist/specification/src/sync/common/ManifestDrivenSchemaProcessor.d.ts.map +1 -1
  36. package/dist/specification/src/sync/common/ManifestDrivenSchemaProcessor.js +0 -3
  37. package/dist/specification/src/sync/common/ManifestDrivenSchemaProcessor.js.map +1 -1
  38. package/dist/specification/src/sync/common/appProvider.d.ts +0 -1
  39. package/dist/specification/src/sync/common/appProvider.d.ts.map +1 -1
  40. package/dist/specification/src/sync/common/appProvider.js +0 -1
  41. package/dist/specification/src/sync/common/appProvider.js.map +1 -1
  42. package/dist/specification/src/sync/common/generate/objectPage.d.ts +0 -1
  43. package/dist/specification/src/sync/common/generate/objectPage.d.ts.map +1 -1
  44. package/dist/specification/src/sync/common/generate/objectPage.js +0 -3
  45. package/dist/specification/src/sync/common/generate/objectPage.js.map +1 -1
  46. package/dist/specification/src/sync/common/generate/utils.d.ts +1 -2
  47. package/dist/specification/src/sync/common/generate/utils.d.ts.map +1 -1
  48. package/dist/specification/src/sync/common/generate/utils.js +1 -2
  49. package/dist/specification/src/sync/common/generate/utils.js.map +1 -1
  50. package/dist/specification/src/sync/common/import/utils.d.ts +0 -1
  51. package/dist/specification/src/sync/common/import/utils.d.ts.map +1 -1
  52. package/dist/specification/src/sync/common/import/utils.js +0 -1
  53. package/dist/specification/src/sync/common/import/utils.js.map +1 -1
  54. package/dist/specification/src/sync/common/rules.js +0 -1
  55. package/dist/specification/src/sync/common/rules.js.map +1 -1
  56. package/dist/specification/src/sync/common/utils.d.ts +13 -2
  57. package/dist/specification/src/sync/common/utils.d.ts.map +1 -1
  58. package/dist/specification/src/sync/common/utils.js +84 -4
  59. package/dist/specification/src/sync/common/utils.js.map +1 -1
  60. package/dist/specification/src/sync/v2/export/exportPageGeneric.d.ts.map +1 -1
  61. package/dist/specification/src/sync/v2/export/exportPageGeneric.js +3 -13
  62. package/dist/specification/src/sync/v2/export/exportPageGeneric.js.map +1 -1
  63. package/dist/specification/src/sync/v2/generate/analyticalListReport.d.ts.map +1 -1
  64. package/dist/specification/src/sync/v2/generate/analyticalListReport.js +46 -0
  65. package/dist/specification/src/sync/v2/generate/analyticalListReport.js.map +1 -1
  66. package/dist/specification/src/sync/v2/generate/schemaAdaptation.d.ts.map +1 -1
  67. package/dist/specification/src/sync/v2/generate/schemaAdaptation.js +28 -1
  68. package/dist/specification/src/sync/v2/generate/schemaAdaptation.js.map +1 -1
  69. package/dist/specification/src/sync/v2/import/importPage.d.ts.map +1 -1
  70. package/dist/specification/src/sync/v2/import/importPage.js +5 -6
  71. package/dist/specification/src/sync/v2/import/importPage.js.map +1 -1
  72. package/dist/specification/src/sync/v4/application.d.ts +1 -1
  73. package/dist/specification/src/sync/v4/application.d.ts.map +1 -1
  74. package/dist/specification/src/sync/v4/application.js +1 -1
  75. package/dist/specification/src/sync/v4/application.js.map +1 -1
  76. package/dist/specification/src/sync/v4/export/actions.d.ts +39 -0
  77. package/dist/specification/src/sync/v4/export/actions.d.ts.map +1 -0
  78. package/dist/specification/src/sync/v4/export/actions.js +99 -0
  79. package/dist/specification/src/sync/v4/export/actions.js.map +1 -0
  80. package/dist/specification/src/sync/v4/export/controls/ObjectPageForm.d.ts +2 -1
  81. package/dist/specification/src/sync/v4/export/controls/ObjectPageForm.d.ts.map +1 -1
  82. package/dist/specification/src/sync/v4/export/controls/ObjectPageForm.js.map +1 -1
  83. package/dist/specification/src/sync/v4/export/controls/ObjectPageFormAction.d.ts +2 -4
  84. package/dist/specification/src/sync/v4/export/controls/ObjectPageFormAction.d.ts.map +1 -1
  85. package/dist/specification/src/sync/v4/export/controls/ObjectPageFormAction.js +2 -21
  86. package/dist/specification/src/sync/v4/export/controls/ObjectPageFormAction.js.map +1 -1
  87. package/dist/specification/src/sync/v4/export/controls/ObjectPageHeader.d.ts +2 -2
  88. package/dist/specification/src/sync/v4/export/controls/ObjectPageHeader.d.ts.map +1 -1
  89. package/dist/specification/src/sync/v4/export/controls/ObjectPageHeader.js.map +1 -1
  90. package/dist/specification/src/sync/v4/export/controls/ObjectPageHeaderAction.d.ts +14 -3
  91. package/dist/specification/src/sync/v4/export/controls/ObjectPageHeaderAction.d.ts.map +1 -1
  92. package/dist/specification/src/sync/v4/export/controls/ObjectPageHeaderAction.js +52 -9
  93. package/dist/specification/src/sync/v4/export/controls/ObjectPageHeaderAction.js.map +1 -1
  94. package/dist/specification/src/sync/v4/export/controls/ObjectPageToolBarAction.d.ts +15 -3
  95. package/dist/specification/src/sync/v4/export/controls/ObjectPageToolBarAction.d.ts.map +1 -1
  96. package/dist/specification/src/sync/v4/export/controls/ObjectPageToolBarAction.js +53 -10
  97. package/dist/specification/src/sync/v4/export/controls/ObjectPageToolBarAction.js.map +1 -1
  98. package/dist/specification/src/sync/v4/export/controls/Table.d.ts +0 -3
  99. package/dist/specification/src/sync/v4/export/controls/Table.d.ts.map +1 -1
  100. package/dist/specification/src/sync/v4/export/controls/Table.js +0 -3
  101. package/dist/specification/src/sync/v4/export/controls/Table.js.map +1 -1
  102. package/dist/specification/src/sync/v4/export/controls/ToolBar.d.ts +9 -2
  103. package/dist/specification/src/sync/v4/export/controls/ToolBar.d.ts.map +1 -1
  104. package/dist/specification/src/sync/v4/export/controls/ToolBar.js +39 -1
  105. package/dist/specification/src/sync/v4/export/controls/ToolBar.js.map +1 -1
  106. package/dist/specification/src/sync/v4/export/controls/ToolBarAction.d.ts +17 -4
  107. package/dist/specification/src/sync/v4/export/controls/ToolBarAction.d.ts.map +1 -1
  108. package/dist/specification/src/sync/v4/export/controls/ToolBarAction.js +76 -19
  109. package/dist/specification/src/sync/v4/export/controls/ToolBarAction.js.map +1 -1
  110. package/dist/specification/src/sync/v4/export/export.d.ts +7 -0
  111. package/dist/specification/src/sync/v4/export/export.d.ts.map +1 -1
  112. package/dist/specification/src/sync/v4/export/export.js +100 -11
  113. package/dist/specification/src/sync/v4/export/export.js.map +1 -1
  114. package/dist/specification/src/sync/v4/export/types.d.ts +2 -0
  115. package/dist/specification/src/sync/v4/export/types.d.ts.map +1 -1
  116. package/dist/specification/src/sync/v4/generate/ListReportUtils.d.ts.map +1 -1
  117. package/dist/specification/src/sync/v4/generate/ListReportUtils.js +19 -17
  118. package/dist/specification/src/sync/v4/generate/ListReportUtils.js.map +1 -1
  119. package/dist/specification/src/sync/v4/generate/actions.d.ts +35 -0
  120. package/dist/specification/src/sync/v4/generate/actions.d.ts.map +1 -0
  121. package/dist/specification/src/sync/v4/generate/actions.js +112 -0
  122. package/dist/specification/src/sync/v4/generate/actions.js.map +1 -0
  123. package/dist/specification/src/sync/v4/generate/fpm-custom-page/annotations.d.ts +3 -3
  124. package/dist/specification/src/sync/v4/generate/fpm-custom-page/annotations.d.ts.map +1 -1
  125. package/dist/specification/src/sync/v4/generate/fpm-custom-page/annotations.js +10 -2
  126. package/dist/specification/src/sync/v4/generate/fpm-custom-page/annotations.js.map +1 -1
  127. package/dist/specification/src/sync/v4/generate/fpm-custom-page/extensions.d.ts +1 -1
  128. package/dist/specification/src/sync/v4/generate/fpm-custom-page/extensions.d.ts.map +1 -1
  129. package/dist/specification/src/sync/v4/generate/fpm-custom-page/extensions.js +3 -2
  130. package/dist/specification/src/sync/v4/generate/fpm-custom-page/extensions.js.map +1 -1
  131. package/dist/specification/src/sync/v4/generate/fpm-custom-page/generator.d.ts.map +1 -1
  132. package/dist/specification/src/sync/v4/generate/fpm-custom-page/generator.js +9 -2
  133. package/dist/specification/src/sync/v4/generate/fpm-custom-page/generator.js.map +1 -1
  134. package/dist/specification/src/sync/v4/generate/fpm-custom-page/utils.js +2 -2
  135. package/dist/specification/src/sync/v4/generate/fpm-custom-page/utils.js.map +1 -1
  136. package/dist/specification/src/sync/v4/generate/listReport.d.ts +25 -5
  137. package/dist/specification/src/sync/v4/generate/listReport.d.ts.map +1 -1
  138. package/dist/specification/src/sync/v4/generate/listReport.js +97 -262
  139. package/dist/specification/src/sync/v4/generate/listReport.js.map +1 -1
  140. package/dist/specification/src/sync/v4/generate/objectPage.d.ts +0 -1
  141. package/dist/specification/src/sync/v4/generate/objectPage.d.ts.map +1 -1
  142. package/dist/specification/src/sync/v4/generate/objectPage.js +8 -14
  143. package/dist/specification/src/sync/v4/generate/objectPage.js.map +1 -1
  144. package/dist/specification/src/sync/v4/import/pages/objectPage.d.ts.map +1 -1
  145. package/dist/specification/src/sync/v4/import/pages/objectPage.js +16 -3
  146. package/dist/specification/src/sync/v4/import/pages/objectPage.js.map +1 -1
  147. package/dist/specification/src/sync/v4/import/utils.d.ts +0 -1
  148. package/dist/specification/src/sync/v4/import/utils.d.ts.map +1 -1
  149. package/dist/specification/src/sync/v4/import/utils.js +0 -1
  150. package/dist/specification/src/sync/v4/import/utils.js.map +1 -1
  151. package/dist/specification/src/sync/v4/utils/utils.d.ts +103 -25
  152. package/dist/specification/src/sync/v4/utils/utils.d.ts.map +1 -1
  153. package/dist/specification/src/sync/v4/utils/utils.js +357 -44
  154. package/dist/specification/src/sync/v4/utils/utils.js.map +1 -1
  155. package/dist/types/src/apiTypes.d.ts +3 -2
  156. package/dist/types/src/apiTypes.d.ts.map +1 -1
  157. package/dist/types/src/apiTypes.js +1 -0
  158. package/dist/types/src/apiTypes.js.map +1 -1
  159. package/dist/types/src/common/types.d.ts +43 -2
  160. package/dist/types/src/common/types.d.ts.map +1 -1
  161. package/dist/types/src/common/types.js +41 -2
  162. package/dist/types/src/common/types.js.map +1 -1
  163. package/dist/types/src/v4/controls/CustomAction.d.ts +133 -19
  164. package/dist/types/src/v4/controls/CustomAction.d.ts.map +1 -1
  165. package/dist/types/src/v4/controls/CustomAction.js.map +1 -1
  166. package/dist/types/src/v4/controls/ObjectPageForm.d.ts +2 -2
  167. package/dist/types/src/v4/controls/ObjectPageForm.d.ts.map +1 -1
  168. package/dist/types/src/v4/controls/ObjectPageHeader.d.ts +22 -3
  169. package/dist/types/src/v4/controls/ObjectPageHeader.d.ts.map +1 -1
  170. package/dist/types/src/v4/controls/ObjectPageToolBar.d.ts +2 -2
  171. package/dist/types/src/v4/controls/ObjectPageToolBar.d.ts.map +1 -1
  172. package/dist/types/src/v4/controls/ToolBar.d.ts +3 -3
  173. package/dist/types/src/v4/controls/ToolBar.d.ts.map +1 -1
  174. package/package.json +8 -8
@@ -55,11 +55,15 @@ exports.findPageV4 = findPageV4;
55
55
  exports.alignSchemaWithTemplateType = alignSchemaWithTemplateType;
56
56
  exports.addCustomActionDefinition = addCustomActionDefinition;
57
57
  exports.addHeaderFooterCustomActionDefinition = addHeaderFooterCustomActionDefinition;
58
+ exports.parseDefinitionName = parseDefinitionName;
58
59
  exports.getManifestPage = getManifestPage;
59
60
  exports.getPageCustomExtensionFile = getPageCustomExtensionFile;
60
61
  exports.getPageCustomViewFile = getPageCustomViewFile;
61
62
  exports.addCustomSectionDefinition = addCustomSectionDefinition;
62
63
  exports.addCustomFilterFieldDefinition = addCustomFilterFieldDefinition;
64
+ exports.importSingleActionSettingsOfReference = importSingleActionSettingsOfReference;
65
+ exports.importGroupActionSettingsOfReference = importGroupActionSettingsOfReference;
66
+ exports.importManifestBasedActionMenuSettingsOfReference = importManifestBasedActionMenuSettingsOfReference;
63
67
  exports.importActionSettingsOfReference = importActionSettingsOfReference;
64
68
  exports.addCustomFieldDefinition = addCustomFieldDefinition;
65
69
  exports.addManifestPathsToProperties = addManifestPathsToProperties;
@@ -80,6 +84,36 @@ exports.DATA_FIELD_FOR_ACTION_GROUP = 'DataFieldForActionGroup';
80
84
  const UI_ANNOTATION_KEY = 'UI';
81
85
  exports.FIELD_SEPARATOR = '::';
82
86
  exports.QUALIFIER_SEPARATOR = '#';
87
+ const ACTION_TYPE = 'actionType';
88
+ const strategyTypeMap = new Map([
89
+ ['', "com.sap.vocabularies.UI.v1.DataFieldForAction" /* UIAnnotationTypes.DataFieldForAction */],
90
+ ['DataFieldForAction', "com.sap.vocabularies.UI.v1.DataFieldForAction" /* UIAnnotationTypes.DataFieldForAction */],
91
+ ['DataFieldForActionGroup', "com.sap.vocabularies.UI.v1.DataFieldForActionGroup" /* UIAnnotationTypes.DataFieldForActionGroup */],
92
+ ['CustomMenu', ux_specification_types_1.CustomUIAnnotationTypes.ManifestBasedActionMenu]
93
+ ]);
94
+ const OP_ACTION_MENU_DEFINITION = {
95
+ actionMenuDefinitionName: ux_specification_types_1.DefinitionName.ObjectPageCustomActionMenu,
96
+ actionMenuActionsDefinitionName: ux_specification_types_1.DefinitionName.ObjectPageCustomActionMenuActions
97
+ };
98
+ const OP_HEADER_ACTION_MENU_DEFINITION = {
99
+ actionMenuDefinitionName: ux_specification_types_1.DefinitionName.ObjectPageHeaderCustomActionMenu,
100
+ actionMenuActionsDefinitionName: ux_specification_types_1.DefinitionName.ObjectPageHeaderCustomActionMenuActions
101
+ };
102
+ const LR_ACTION_MENU_DEFINITION = {
103
+ actionMenuDefinitionName: ux_specification_types_1.DefinitionName.CustomActionMenu,
104
+ actionMenuActionsDefinitionName: ux_specification_types_1.DefinitionName.CustomActionMenuActions
105
+ };
106
+ const LR_ACTION_VIEW_MENU_DEFINITION = {
107
+ actionMenuDefinitionName: ux_specification_types_1.DefinitionName.ViewCustomActionMenu,
108
+ actionMenuActionsDefinitionName: ux_specification_types_1.DefinitionName.ViewCustomActionMenuActions
109
+ };
110
+ const actionMenuDefinitionNameMap = new Map([
111
+ [ux_specification_types_1.DefinitionName.CustomTableActionOP, OP_ACTION_MENU_DEFINITION],
112
+ [ux_specification_types_1.DefinitionName.CustomFormActionOP, OP_ACTION_MENU_DEFINITION],
113
+ [ux_specification_types_1.DefinitionName.CustomTableAction, LR_ACTION_MENU_DEFINITION],
114
+ [ux_specification_types_1.DefinitionName.CustomHeaderActionOP, OP_HEADER_ACTION_MENU_DEFINITION],
115
+ [ux_specification_types_1.DefinitionName.ViewCustomAction, LR_ACTION_VIEW_MENU_DEFINITION]
116
+ ]);
83
117
  /**
84
118
  * Returns a comparator function to sort objects by their property index.
85
119
  *
@@ -194,18 +228,24 @@ function getExtensionDetails(extension, extensionDefinitionName, extId, actionTy
194
228
  /**
195
229
  * Post-processing of custom extensions that are left after the first loop of adding extensions, i.e. custom extensions referring to other custom extensions.
196
230
  *
197
- * @param remainingExtensions - list of custom extensions that are left for post-processing
198
- * @param extensionDefinitionName - custom extension definition name, different in LR and OP
199
- * @param sortedExtArray - sorted array of annotation-based extensions, to be updated
200
- * @param logger - logger for error messages
201
- * @param {boolean} forceAdd - add self-referencing custom extensions after other additions
231
+ * @param {CustomExtensions} remainingExtensions - An object containing the remaining extensions to process.
232
+ * @param {string} extensionDefinitionName - The name of the extension definition to refer to.
233
+ * @param {[string, unknown][]} sortedExtArray - A sorted array of existing extensions represented as key-value pairs.
234
+ * @param {ExtensionLogger} logger - The logger used for logging errors and warnings during the adjustment process.
235
+ * @param {boolean} [forceAdd=false] - Flag indicating whether to force adding extensions even if proper anchor/placement is not found.
202
236
  */
203
237
  function adjustCustomExtReferringToCustomExt(remainingExtensions, extensionDefinitionName, sortedExtArray, logger, forceAdd = false) {
204
238
  const initialRemaining = Object.entries(remainingExtensions).length;
205
239
  for (const extId of Object.keys(remainingExtensions)) {
240
+ // make sure that we do not add the same extension twice
241
+ const isAlreadyAdded = sortedExtArray.find((element) => element[0] === extId) !== undefined;
242
+ if (isAlreadyAdded) {
243
+ delete remainingExtensions[extId];
244
+ continue;
245
+ }
206
246
  const extension = remainingExtensions[extId];
207
247
  // Detect description based on extension in manifest
208
- const newCustomExt = getExtensionDetails(extension, extensionDefinitionName, extId);
248
+ const newCustomExt = getExtensionDetails(extension, extensionDefinitionName, extId, ux_specification_types_1.ActionType.Custom);
209
249
  if (extension.position?.anchor && extension.position?.placement) {
210
250
  const targetIndex = sortedExtArray.findIndex((element) => element[0] === extension.position.anchor);
211
251
  if (targetIndex > -1) {
@@ -365,17 +405,20 @@ function handleInvalidExtension(logger, extensionId, sortedExtensionsArray, newE
365
405
  delete localExtensions[extensionId];
366
406
  }
367
407
  /**
368
- * Adds extension at the right position of the sorted array of annotation-based nodes.
408
+ * Adds extension entries to a sorted array of extensions based on specific rules,
409
+ * including using anchors, callbacks, and custom templates.
369
410
  *
370
- * @param extensions - list of extensions in manifest
371
- * @param sortedExtensionsArray - sorted array of annotation-based nodes, to be enhanced by extensions
372
- * @param extensionDefinitionName - extension definition name, different in LR and OP
373
- * @param templatePropertyName - The name of the property in the template to be used for processing.
374
- * @param logger - logger for error messages
375
- * @param ignoreAnnotationAnchors - calculation should ignore anchors referenced to annotation nodes. Used when annotations sections are merged.
376
- * @returns Sorted array of annotation-based nodes, enhanced by extensions
411
+ * @param {CustomExtensions} extensions - The object containing custom extensions to be added to the array.
412
+ * @param {ActionDetails[]} sortedExtensionsArray - The array of sorted extensions to which new extensions will be added.
413
+ * @param {string} extensionDefinitionName - The definition name associated with the extensions being added.
414
+ * @param {TemplatePropertyName | TemplatePropertyName[]} [templatePropertyName=TemplatePropertyName.Template] -
415
+ * The property name(s) to check for existence in an extension; used to determine compatibility.
416
+ * @param {ExtensionLogger} [logger] - An optional logger to handle logging of invalid extensions or other events.
417
+ * @param {boolean} [ignoreAnnotationAnchors=false] - A flag to indicate whether extension anchors should be ignored.
418
+ * @returns {ActionDetails[]} The updated sorted extensions array, including newly added and valid extensions.
377
419
  */
378
- function addExtensionToArray(extensions, sortedExtensionsArray, extensionDefinitionName, templatePropertyName = 'template', logger, ignoreAnnotationAnchors = false) {
420
+ function addExtensionToArray(extensions, sortedExtensionsArray, extensionDefinitionName, templatePropertyName = ux_specification_types_1.TemplatePropertyName.Template, logger, ignoreAnnotationAnchors = false) {
421
+ templatePropertyName = Array.isArray(templatePropertyName) ? templatePropertyName : [templatePropertyName];
379
422
  const annotationEntries = [...sortedExtensionsArray];
380
423
  const localExtensions = { ...extensions };
381
424
  const localExtensionsToSkip = getLocalExtensionsToSkip(localExtensions, annotationEntries);
@@ -392,7 +435,8 @@ function addExtensionToArray(extensions, sortedExtensionsArray, extensionDefinit
392
435
  handleInvalidExtension(logger, extensionId, sortedExtensionsArray, newExtensionReference, localExtensions);
393
436
  continue;
394
437
  }
395
- if (!(templatePropertyName in extension)) {
438
+ const hasUnsupportedExtensionType = templatePropertyName.every((propertyName) => !(propertyName in extension));
439
+ if (hasUnsupportedExtensionType) {
396
440
  // Skip regular entries(columns, actions, etc.)
397
441
  delete localExtensions[extensionId];
398
442
  continue;
@@ -413,7 +457,7 @@ function addExtensionToArray(extensions, sortedExtensionsArray, extensionDefinit
413
457
  }
414
458
  if (Object.keys(localExtensions).length > 0) {
415
459
  //Second loop is necessary for custom columns that refer to custom columns
416
- adjustCustomExtReferringToCustomExt(localExtensions, extensionDefinitionName, sortedExtensionsArray, logger);
460
+ adjustCustomExtReferringToCustomExt(localExtensions, extensionDefinitionName, sortedExtensionsArray, logger, false);
417
461
  }
418
462
  return sortedExtensionsArray;
419
463
  }
@@ -642,7 +686,6 @@ function addActionRecordToSchema(lineItemDefinitionParams, createRef = true) {
642
686
  *
643
687
  * @param {AddLineItemDefinitionParams} lineItemDefinitionParams - Parameters that define the line item, including data, record, path, index, and actions.
644
688
  * @param {boolean} [createRef] - Indicates whether to create a reference for the action definition or to use an inline object.
645
- * @returns {void} - Does not return any value.
646
689
  */
647
690
  function addGroupActionRecordToSchema(lineItemDefinitionParams, createRef = true) {
648
691
  const { lineItemData, lineItemRecord, lineItemPath, index, actions } = lineItemDefinitionParams;
@@ -686,7 +729,6 @@ function addGroupActionRecordToSchema(lineItemDefinitionParams, createRef = true
686
729
  * @param {boolean} data.lineItemRecord.Inline - Indicates whether the line item is inline.
687
730
  * @param {boolean} data.lineItemRecord.Determining - Indicates if the line item is determining.
688
731
  * @param {boolean} data.lineItemDefinition - Indicates whether the line item definition is present.
689
- * @returns {void} This method does not return a value.
690
732
  */
691
733
  function addLineItemActionDefinition(data) {
692
734
  const { lineItemRecord, lineItemDefinition } = data;
@@ -701,7 +743,6 @@ function addLineItemActionDefinition(data) {
701
743
  * Adds a line item record to the provided schema based on the definition parameters.
702
744
  *
703
745
  * @param {AddLineItemDefinitionParams} lineItemDefinitionParams - The parameters defining the line item data, schema information, and record.
704
- * @returns {void} This function does not return a value.
705
746
  */
706
747
  function addLineItemRecordToSchema(lineItemDefinitionParams) {
707
748
  const { lineItemData, lineItemRecord, lineItemDefinition, lineItemPath, index, columnDefinitionName } = lineItemDefinitionParams;
@@ -848,7 +889,6 @@ function addEnumForActionAnchor(appSchema, definitionId, positionName = ux_speci
848
889
  * @param {string} tableDefinitionName - The name of the table definition in the schema.
849
890
  * @param {string} columnsDefinitionName - The name of the columns definition used to extract column enumerations.
850
891
  * @param {EntityType} [entityType] - Optional entity type for additional context when retrieving column definitions.
851
- * @returns {void} No return value as this function modifies the schema in place.
852
892
  */
853
893
  function addEnumForEnableMassEdit(appSchema, tableDefinitionName, columnsDefinitionName, entityType) {
854
894
  const FIELD_PROPERTIES = ['visibleFields', 'ignoredFields'];
@@ -906,7 +946,10 @@ function initializeCreationModeSchema(appSchema, lineItemId, entityType, definit
906
946
  const specificCreationModeDefinitionName = (0, common_1.getFacetDefinitionKey)(definitionName, lineItemId);
907
947
  const specificCreationModeDefinition = (appSchema.definitions[specificCreationModeDefinitionName] = structuredClone(appSchema.definitions[definitionName]));
908
948
  const creationFieldsDefinition = specificCreationModeDefinition.properties[ux_specification_types_1.PropertyName.creationFields];
909
- creationFieldsDefinition.items['oneOf'] = [...columnOneOfEnums, ...fieldGroups];
949
+ const creationFieldsDefinitionItems = creationFieldsDefinition.items;
950
+ creationFieldsDefinitionItems['oneOf'] = [...columnOneOfEnums, ...fieldGroups];
951
+ // Entries of one of are translatable using 'service' i18n bundle
952
+ creationFieldsDefinitionItems.i18nBundle = 'service';
910
953
  creationFieldsDefinition.uniqueItems = true;
911
954
  return specificCreationModeDefinitionName;
912
955
  }
@@ -992,14 +1035,15 @@ function alignSchemaWithTemplateType(appSchema, templateType) {
992
1035
  /**
993
1036
  * Common function for enhancing LineItems, FieldGroups and Custom Section definitions of app schema by custom action definitions.
994
1037
  *
995
- * @param appSchema - app-specific JSON schema
996
- * @param v4Page - actual page in the manifest
997
- * @param logger - logger for error messages
998
- * @param customActionDefinitionName - definition name of custom action
999
- * @param sectionDefinitionName - identifier of the current object page section in schema
1000
- * @param sectionIdInManifest - identifier of the current object page section in manifest
1038
+ * @param appSchema The application schema where the custom action definition will be added.
1039
+ * @param v4Page The V4 page configuration object that contains metadata and settings for the page.
1040
+ * @param logger A logging instance for logging warnings or errors during the processing.
1041
+ * @param customActionDefinitionName The name of the custom action definition to be added. Defaults to `DefinitionName.CustomTableAction`.
1042
+ * @param sectionDefinitionName The name of the section definition within the schema to which the action definition will be added.
1043
+ * @param sectionIdInManifest Optional: The section ID in the manifest, used to derive the configuration ID.
1044
+ * @param lineItemId Optional: The ID of the line item, if applicable.
1001
1045
  */
1002
- function addCustomActionDefinition(appSchema, v4Page, logger, customActionDefinitionName = ux_specification_types_1.DefinitionName.CustomTableAction, sectionDefinitionName = '', sectionIdInManifest = '') {
1046
+ function addCustomActionDefinition(appSchema, v4Page, logger, customActionDefinitionName = ux_specification_types_1.DefinitionName.CustomTableAction, sectionDefinitionName = '', sectionIdInManifest = '', lineItemId) {
1003
1047
  const definition = appSchema.definitions[sectionDefinitionName];
1004
1048
  if (!definition) {
1005
1049
  return;
@@ -1031,7 +1075,16 @@ function addCustomActionDefinition(appSchema, v4Page, logger, customActionDefini
1031
1075
  actions = v4Page.options?.settings?.controlConfiguration?.[configId]?.['actions'];
1032
1076
  }
1033
1077
  if (actions) {
1034
- sortedActionsArray = addExtensionToArray(actions, sortedActionsArray, customActionDefinitionName, 'press', logger);
1078
+ // Add custom actions and custom action menus to the actions array
1079
+ const parameters = {
1080
+ extensions: actions,
1081
+ appSchema,
1082
+ customActionDefinitionName,
1083
+ initialActionDetailsList: sortedActionsArray,
1084
+ logger,
1085
+ lineItemId
1086
+ };
1087
+ sortedActionsArray = addActionsToArray(parameters);
1035
1088
  }
1036
1089
  // Adjust propertyIndex
1037
1090
  if (sortedActionsArray) {
@@ -1067,7 +1120,15 @@ function addHeaderFooterCustomActionDefinition(appSchema, v4Page, logger, custom
1067
1120
  actions = v4Page.options?.settings?.content?.footer?.['actions'];
1068
1121
  }
1069
1122
  if (actions) {
1070
- sortedActionsArray = addExtensionToArray(actions, sortedActionsArray, customActionDefinitionName, 'press', logger);
1123
+ // Add custom actions and custom action menus to the actions array
1124
+ const parameters = {
1125
+ extensions: actions,
1126
+ appSchema,
1127
+ customActionDefinitionName,
1128
+ initialActionDetailsList: sortedActionsArray,
1129
+ logger
1130
+ };
1131
+ sortedActionsArray = addActionsToArray(parameters);
1071
1132
  }
1072
1133
  // Adjust propertyIndex
1073
1134
  const sortedActionsAsObject = {};
@@ -1079,6 +1140,195 @@ function addHeaderFooterCustomActionDefinition(appSchema, v4Page, logger, custom
1079
1140
  }
1080
1141
  appSchema.definitions[sectionId].properties = sortedActionsAsObject;
1081
1142
  }
1143
+ /**
1144
+ * Adds actions and custom action menus to an array of initial actions using specified parameters.
1145
+ *
1146
+ * @param params - An object containing the parameters for adding actions to the array:
1147
+ * - actions: The original actions to be processed.
1148
+ * - initialActionsArray: The array to which actions should be added.
1149
+ * - customActionDefinitionName: The name of the custom action definition.
1150
+ * - appSchema: The application schema used for processing.
1151
+ * - logger: An object used for logging information during processing.
1152
+ * @returns An array of action details after processing and adding extensions.
1153
+ */
1154
+ function addActionsToArray(params) {
1155
+ const { extensions, initialActionDetailsList, customActionDefinitionName, logger } = params;
1156
+ // Add custom actions
1157
+ let actionDetailsList = addExtensionToArray(extensions, initialActionDetailsList, customActionDefinitionName, [ux_specification_types_1.TemplatePropertyName.Press, ux_specification_types_1.TemplatePropertyName.Menu], logger);
1158
+ const processActionMenusParams = {
1159
+ ...params,
1160
+ initialActionDetailsList: actionDetailsList
1161
+ };
1162
+ actionDetailsList = processActionMenus(processActionMenusParams);
1163
+ return actionDetailsList;
1164
+ }
1165
+ /**
1166
+ * Processes action menus by identifying menu-type actions within the provided extensions and updating the list of action details accordingly.
1167
+ *
1168
+ * @param {ActionProcessingParameters} params - An object containing required parameters for processing action menus. It includes:
1169
+ * - extensions: A map of extension data where the keys are extension IDs and the values are extension definitions.
1170
+ * - initialActionDetailsList: A list of action details, each represented as a tuple with the action ID and action definition.
1171
+ * @returns {Array} An updated list of action details after processing any menu-type actions.
1172
+ */
1173
+ function processActionMenus(params) {
1174
+ const { extensions, initialActionDetailsList } = params;
1175
+ let actionDetailsList = [...initialActionDetailsList];
1176
+ // Currently, all actions were initialized as custom actions. We need to check if the action is a menu and if so,
1177
+ // we need to process it differently.
1178
+ for (const extensionId in extensions) {
1179
+ const extension = extensions[extensionId];
1180
+ const actionDetails = actionDetailsList.find(([actionId]) => actionId === extensionId);
1181
+ if (Object.keys(extension).includes(ux_specification_types_1.PropertyName.menu) && actionDetails) {
1182
+ const [, actionDefinition] = actionDetails;
1183
+ actionDetailsList = processActionMenu(params, extension, actionDefinition, actionDetailsList, extensionId);
1184
+ }
1185
+ }
1186
+ return actionDetailsList;
1187
+ }
1188
+ /**
1189
+ * Retrieves a reference to a menu entry definition based on the provided parameters.
1190
+ *
1191
+ * @param {string} $ref - The reference string used to identify the menu entry definition.
1192
+ * @param {string} actionMenuDefinitionName - The name of the action menu definition.
1193
+ * @param {Definition} appSchema - The application schema containing the definitions.
1194
+ * @returns {string} The constructed link or reference for the specified menu entry definition.
1195
+ */
1196
+ function getMenuEntryDefinitionLink($ref, actionMenuDefinitionName, appSchema) {
1197
+ const definitionName = (0, utils_1.getDefinitionKey)($ref);
1198
+ const { baseDefinitionName, definitionQualifier } = parseDefinitionName(definitionName);
1199
+ // incorrect definition name - probably a reference to an intent based navigation action
1200
+ if (baseDefinitionName.includes(exports.FIELD_SEPARATOR)) {
1201
+ return $ref;
1202
+ }
1203
+ const menuEntryDefinitionQualifier = definitionQualifier
1204
+ ? `${actionMenuDefinitionName}${exports.FIELD_SEPARATOR}${definitionQualifier}`
1205
+ : actionMenuDefinitionName;
1206
+ const menuEntryDefinitionRef = (0, common_1.getFacetDefinitionKey)(baseDefinitionName, menuEntryDefinitionQualifier);
1207
+ const menuEntryDefinitionLink = (0, common_1.getFacetDefinitionLink)(baseDefinitionName, menuEntryDefinitionQualifier);
1208
+ const menuEntryDefinition = appSchema.definitions[menuEntryDefinitionRef];
1209
+ if (!menuEntryDefinition) {
1210
+ const originalDefinition = appSchema.definitions[definitionName];
1211
+ const menuEntryDefinition = (0, common_1.parseSchemaDefinition)(baseDefinitionName, menuEntryDefinitionQualifier, appSchema);
1212
+ for (const originalDefinitionKey of Object.keys(originalDefinition)) {
1213
+ if (menuEntryDefinition[originalDefinitionKey] === undefined) {
1214
+ menuEntryDefinition[originalDefinitionKey] = originalDefinition[originalDefinitionKey];
1215
+ }
1216
+ }
1217
+ // some properties doesn't make sense for menu entries
1218
+ delete menuEntryDefinition.properties[ux_specification_types_1.PropertyName.position];
1219
+ delete menuEntryDefinition.properties[ux_specification_types_1.PropertyName.priority];
1220
+ }
1221
+ return menuEntryDefinitionLink;
1222
+ }
1223
+ /**
1224
+ * Determines the appropriate action menu definition name based on a custom action definition name.
1225
+ *
1226
+ * @param {string} customActionDefinitionName - The custom action definition name to be parsed and matched.
1227
+ * @returns {ActionMenuDefinitionName} The corresponding action menu definition name, or a default value if not found.
1228
+ */
1229
+ function determineActionMenuDefinitionName(customActionDefinitionName) {
1230
+ const { baseDefinitionName } = parseDefinitionName(customActionDefinitionName);
1231
+ return actionMenuDefinitionNameMap.get(baseDefinitionName) ?? LR_ACTION_MENU_DEFINITION;
1232
+ }
1233
+ /**
1234
+ * Parses a given definition name into its base name and optional qualifier.
1235
+ *
1236
+ * @param definitionName The definition name to parse. This should be a string in the format "BaseName" or "BaseName<Qualifier>".
1237
+ * @returns An object containing the base definition name and, if applicable, its qualifier.
1238
+ * If there is no qualifier, it will return undefined for the qualifier field.
1239
+ */
1240
+ function parseDefinitionName(definitionName = '') {
1241
+ const match = /^([^<]*)(?:<(.*)>)?$/.exec(definitionName);
1242
+ if (!match) {
1243
+ return { baseDefinitionName: definitionName };
1244
+ }
1245
+ const [, baseDefinitionName, definitionQualifier] = match;
1246
+ return {
1247
+ baseDefinitionName: baseDefinitionName,
1248
+ definitionQualifier: definitionQualifier ?? undefined
1249
+ };
1250
+ }
1251
+ /**
1252
+ * Updates the custom menu's default action to include a list of valid options based on the provided menu schema.
1253
+ *
1254
+ * @param {Definition} customMenuDefinition - The definition object for the custom menu, where the default action will be updated.
1255
+ * @param {Record<string, SchemaDefinition>} [menu={}] - A mapping of menu items to their schema definitions, used to generate valid options for the default action.
1256
+ */
1257
+ function setCustomMenuDefaultAction(customMenuDefinition, menu = {}) {
1258
+ if (customMenuDefinition.properties[ux_specification_types_1.PropertyName.defaultAction]) {
1259
+ const menuOneOfValues = Object.keys(menu).map((value) => ({
1260
+ const: value,
1261
+ description: menu[value].description
1262
+ }));
1263
+ customMenuDefinition.properties[ux_specification_types_1.PropertyName.defaultAction][ux_specification_types_1.PropertyName.oneOf] = menuOneOfValues;
1264
+ }
1265
+ }
1266
+ /**
1267
+ * Retrieves the description of a menu entry from its schema definition.
1268
+ *
1269
+ * @param menuEntryDefinition The schema definition of the menu entry, including its reference information.
1270
+ * @param appSchema The complete application schema containing definitions for the menu entries.
1271
+ * @returns The description of the menu entry if found, or an empty string if no description is available.
1272
+ */
1273
+ function getMenuEntryDescription(menuEntryDefinition, appSchema) {
1274
+ const definitionKey = (0, utils_1.getDefinitionKey)(menuEntryDefinition.$ref);
1275
+ const definition = appSchema.definitions[definitionKey];
1276
+ return menuEntryDefinition?.description ?? definition?.description ?? '';
1277
+ }
1278
+ /**
1279
+ * Processes an action menu for a custom extension, updating the schema definition and action details list accordingly.
1280
+ *
1281
+ * @param {ActionProcessingParameters} params The parameters required for action menu processing, including `actionMenu`, `actionMenuActions`, `appSchema`, and `lineItemId`.
1282
+ * @param {CustomExtension} extension The custom extension that contains the action menu configuration.
1283
+ * @param {SchemaDefinition} actionDefinition The schema definition object to be populated with details of the custom action menu.
1284
+ * @param {ActionDetails[]} initialDetailsList The initial list of action details to be processed and modified.
1285
+ * @param {string} extensionId The unique identifier for the extension being processed.
1286
+ * @returns {ActionDetails[] | undefined} Returns the updated list of action details if processing occurs; otherwise, returns `undefined` if the extension is not a custom action menu.
1287
+ */
1288
+ function processActionMenu(params, extension, actionDefinition, initialDetailsList, extensionId) {
1289
+ // if the extension isn't a custom action menu, don't do anything
1290
+ if (!(ux_specification_types_1.TemplatePropertyName.Menu in extension)) {
1291
+ return undefined;
1292
+ }
1293
+ const { customActionDefinitionName, appSchema, lineItemId } = params;
1294
+ const detailsList = [...initialDetailsList];
1295
+ const { actionMenuDefinitionName, actionMenuActionsDefinitionName } = determineActionMenuDefinitionName(customActionDefinitionName);
1296
+ // Prepare submenu entries to be processed
1297
+ const menu = extension[ux_specification_types_1.TemplatePropertyName.Menu] ?? [];
1298
+ const properties = {};
1299
+ // For forms and tables, the id should contain both the section and action names
1300
+ const extendedExtensionId = lineItemId ? `${extensionId}${exports.FIELD_SEPARATOR}${lineItemId}` : extensionId;
1301
+ // Create the specific action menu definition in the schema based on the generic action menu definition
1302
+ const customMenuDefinition = (0, common_1.parseSchemaDefinition)(actionMenuDefinitionName, extendedExtensionId, appSchema);
1303
+ actionDefinition.$ref = (0, common_1.getFacetDefinitionLink)(actionMenuDefinitionName, extendedExtensionId);
1304
+ actionDefinition[ux_specification_types_1.SchemaTag.actionType] = ux_specification_types_1.ActionType.CustomMenu;
1305
+ const customMenuActionsDefinition = (0, common_1.parseSchemaDefinition)(actionMenuActionsDefinitionName, extendedExtensionId, appSchema);
1306
+ const customMenuActionsDefinitionLink = (0, common_1.getFacetDefinitionLink)(actionMenuActionsDefinitionName, extendedExtensionId);
1307
+ // for manifest based menu actions, we need to store the menu entries from the manifest
1308
+ actionDefinition[ux_specification_types_1.PropertyName.menu] = menu;
1309
+ // Add the menu items to the action menu definition
1310
+ menu.forEach((menuEntry, propertyIndex) => {
1311
+ const sortedExtensionIndex = detailsList.findIndex(([entry]) => entry === menuEntry);
1312
+ // If the list of actions contains the menu entry, add the menu entry to the properties of the custom action menu
1313
+ // and remove the extension reference from the list of actions
1314
+ if (sortedExtensionIndex !== -1) {
1315
+ const menuEntryDefinition = detailsList[sortedExtensionIndex][1];
1316
+ menuEntryDefinition.propertyIndex = propertyIndex;
1317
+ menuEntryDefinition.isViewNode = true;
1318
+ menuEntryDefinition.$ref = getMenuEntryDefinitionLink(menuEntryDefinition.$ref, actionMenuDefinitionName, appSchema);
1319
+ menuEntryDefinition.description = getMenuEntryDescription(menuEntryDefinition, appSchema);
1320
+ properties[menuEntry] = menuEntryDefinition;
1321
+ detailsList.splice(sortedExtensionIndex, 1);
1322
+ }
1323
+ });
1324
+ customMenuDefinition.description = actionDefinition.description;
1325
+ // Update the properties of the custom action menu definition with the menu items
1326
+ const actions = customMenuDefinition.properties[ux_specification_types_1.PropertyName.actions];
1327
+ setCustomMenuDefaultAction(customMenuDefinition, properties);
1328
+ customMenuActionsDefinition.properties = properties;
1329
+ actions.$ref = customMenuActionsDefinitionLink;
1330
+ return detailsList;
1331
+ }
1082
1332
  /**
1083
1333
  * Method returns page from manifest by passed page key.
1084
1334
  *
@@ -1140,7 +1390,7 @@ function getPageCustomExtensionFile(files, page, manifest, xmlType, extensionNam
1140
1390
  let baseName = fileParts.pop();
1141
1391
  baseName = `${baseName}.${xmlType}.${fileExtension}`;
1142
1392
  const extPath = (0, path_1.join)(...fileParts, baseName);
1143
- const file = files.find((file) => file.dataSourceUri.endsWith(extPath));
1393
+ const file = (files ?? []).find((file) => file.dataSourceUri.endsWith(extPath));
1144
1394
  if (file) {
1145
1395
  const settings = page.options?.settings;
1146
1396
  return {
@@ -1199,7 +1449,7 @@ function addCustomSectionDefinition(appSchema, definition, v4Page, customSection
1199
1449
  const section = v4Page.options?.settings?.content?.body?.sections?.[facetKey];
1200
1450
  if (section && 'subSections' in section) {
1201
1451
  // add extension to subsection of section
1202
- sortedSectionsArray = addExtensionToArray(section.subSections, sortedSectionsArray, customSectionRef, 'template', logger, isMergedSections);
1452
+ sortedSectionsArray = addExtensionToArray(section.subSections, sortedSectionsArray, customSectionRef, ux_specification_types_1.TemplatePropertyName.Template, logger, isMergedSections);
1203
1453
  }
1204
1454
  }
1205
1455
  else if (customSectionRef.includes(ux_specification_types_1.DefinitionName.ObjectPageCustomHeaderSectionFragment)) {
@@ -1207,7 +1457,7 @@ function addCustomSectionDefinition(appSchema, definition, v4Page, customSection
1207
1457
  const header = v4Page.options?.settings?.content?.header;
1208
1458
  if (header && 'facets' in header) {
1209
1459
  // add extension to header section
1210
- sortedSectionsArray = addExtensionToArray(header.facets, sortedSectionsArray, customSectionRef, 'template', logger, isMergedSections);
1460
+ sortedSectionsArray = addExtensionToArray(header.facets, sortedSectionsArray, customSectionRef, ux_specification_types_1.TemplatePropertyName.Template, logger, isMergedSections);
1211
1461
  }
1212
1462
  }
1213
1463
  else {
@@ -1215,7 +1465,7 @@ function addCustomSectionDefinition(appSchema, definition, v4Page, customSection
1215
1465
  const sections = v4Page.options?.settings?.content?.body?.sections;
1216
1466
  if (sections) {
1217
1467
  // add extension to sections section
1218
- sortedSectionsArray = addExtensionToArray(sections, sortedSectionsArray, customSectionRef, 'template', logger, isMergedSections);
1468
+ sortedSectionsArray = addExtensionToArray(sections, sortedSectionsArray, customSectionRef, ux_specification_types_1.TemplatePropertyName.Template, logger, isMergedSections);
1219
1469
  }
1220
1470
  }
1221
1471
  // Adjust propertyIndex
@@ -1252,7 +1502,7 @@ function addCustomFilterFieldDefinition(appSchema, definition, v4Page) {
1252
1502
  const selectionFieldsEntry = v4Page.options?.settings?.controlConfiguration?.[`@${"com.sap.vocabularies.UI.v1.SelectionFields" /* UIAnnotationTerms.SelectionFields */}`];
1253
1503
  if (typeof selectionFieldsEntry === 'object' && 'filterFields' in selectionFieldsEntry) {
1254
1504
  // add extension to subsection of section
1255
- sortedFilterFieldsArray = addExtensionToArray(selectionFieldsEntry.filterFields, sortedFilterFieldsArray, ux_specification_types_1.DefinitionName.CustomFilterField, 'template');
1505
+ sortedFilterFieldsArray = addExtensionToArray(selectionFieldsEntry.filterFields, sortedFilterFieldsArray, ux_specification_types_1.DefinitionName.CustomFilterField, ux_specification_types_1.TemplatePropertyName.Template);
1256
1506
  }
1257
1507
  // Adjust propertyIndex
1258
1508
  for (let index = 0; index < sortedFilterFieldsArray.length; index++) {
@@ -1271,7 +1521,6 @@ function addCustomFilterFieldDefinition(appSchema, definition, v4Page) {
1271
1521
  * @param {object} importActionParams - Parameters required for importing action settings, including schema, factory, and action specifications.
1272
1522
  * @param {string} key - The key used to identify the specific configuration or schema definition.
1273
1523
  * @param {boolean} [keepEmptyAction] - Determines whether to keep empty actions in the configuration object.
1274
- * @returns {void} This method does not return any value.
1275
1524
  */
1276
1525
  function importActionToConfigurationObject(importActionParams, key, keepEmptyAction = false) {
1277
1526
  const { appSchema, factory, actionsInConfig, actionKey, manifest, routingId, manifestSectionId, targetAnnotation } = importActionParams;
@@ -1294,7 +1543,6 @@ function importActionToConfigurationObject(importActionParams, key, keepEmptyAct
1294
1543
  *
1295
1544
  * @param {ImportActionSettingsOfReferenceParams} importActionParams - The parameters required for importing action settings, including property definitions.
1296
1545
  * @param {Definition} definitionOfReference - The reference definition object used to resolve the action.
1297
- * @returns {void} This function does not return a value.
1298
1546
  */
1299
1547
  function importSingleActionSettingsOfReference(importActionParams, definitionOfReference) {
1300
1548
  const { actionPropertyDefinition } = importActionParams;
@@ -1310,13 +1558,21 @@ function importSingleActionSettingsOfReference(importActionParams, definitionOfR
1310
1558
  */
1311
1559
  function importGroupActionSettingsOfReference(importActionParams, definitionOfReference) {
1312
1560
  const { actionPropertyDefinition, appSchema, actionsInConfig, actionKey } = importActionParams;
1561
+ let resolvedDefinitionOfReference = definitionOfReference;
1562
+ let resolvedDefinitionKey = (0, utils_1.getDefinitionKey)(resolvedDefinitionOfReference.$ref ?? actionPropertyDefinition.$ref);
1563
+ /* Some action groups (e.g. form group actions) have wrapper definition in the schema, in such cases we need to use the referenced definition. */
1564
+ const hasActionGroupWrapper = (0, utils_1.getDefinitionKey)(definitionOfReference.$ref) === `ObjectPageFormActionGroup<${resolvedDefinitionKey}>`;
1565
+ if (hasActionGroupWrapper) {
1566
+ resolvedDefinitionKey = (0, utils_1.getDefinitionKey)(definitionOfReference.$ref);
1567
+ resolvedDefinitionOfReference = appSchema.definitions[resolvedDefinitionKey];
1568
+ }
1313
1569
  // create an instance of the action group in the configuration object
1314
1570
  const key = (0, utils_1.getDefinitionKey)(definitionOfReference.$ref ?? actionPropertyDefinition.$ref);
1315
1571
  importActionToConfigurationObject(importActionParams, key, true);
1316
1572
  // newly created action group instance is available in the actionsInConfig object
1317
1573
  const actionGroup = actionsInConfig[actionKey];
1318
1574
  // fill the action group with the action settings of the group action
1319
- const { properties } = definitionOfReference;
1575
+ const { properties } = resolvedDefinitionOfReference;
1320
1576
  for (const propertyKey in properties) {
1321
1577
  const actionInGroupProperty = properties[propertyKey];
1322
1578
  const actionInGroupPropertyKey = (0, utils_1.getDefinitionKey)(actionInGroupProperty['$ref']);
@@ -1332,21 +1588,78 @@ function importGroupActionSettingsOfReference(importActionParams, definitionOfRe
1332
1588
  }
1333
1589
  (0, common_1.removeEmptyStructure)(actionsInConfig, actionKey);
1334
1590
  }
1591
+ /**
1592
+ * Imports and updates the action menu settings in a configuration object based on a given reference definition and related action parameters.
1593
+ *
1594
+ * @param {ImportActionSettingsOfReferenceParams} importActionParams - An object containing details such as the action property definition, application schema, actions configuration, and action key. These parameters are used for resolving and importing the settings.
1595
+ * @param {Definition} definitionOfReference - The reference definition object which includes properties and other settings required to define action menus and their related configurations.
1596
+ */
1597
+ function importManifestBasedActionMenuSettingsOfReference(importActionParams, definitionOfReference) {
1598
+ const { actionPropertyDefinition, appSchema, actionsInConfig, actionKey } = importActionParams;
1599
+ // create an instance of the menu action in the configuration object
1600
+ const key = (0, utils_1.getDefinitionKey)(definitionOfReference.$ref ?? actionPropertyDefinition.$ref);
1601
+ importActionToConfigurationObject(importActionParams, key, true);
1602
+ // newly created menu action instance is available in the actionsInConfig object
1603
+ const menuAction = actionsInConfig[actionKey];
1604
+ menuAction[ux_specification_types_1.PropertyName.menu] = actionPropertyDefinition[ux_specification_types_1.PropertyName.menu];
1605
+ menuAction[ux_specification_types_1.PropertyName.actions] = {};
1606
+ menuAction[ux_specification_types_1.PropertyName.text] = definitionOfReference.description;
1607
+ const actionsDefinitionKey = (0, utils_1.getDefinitionKey)(definitionOfReference?.properties?.[ux_specification_types_1.PropertyName.actions]?.$ref);
1608
+ const actionsDefinition = appSchema.definitions[actionsDefinitionKey];
1609
+ // fill the action menu with the action settings of the menu action
1610
+ const actions = actionsDefinition?.properties ?? {};
1611
+ for (const action in actions) {
1612
+ const actionInMenuActionProperty = actions[action];
1613
+ const actionInMenuActionPropertyKey = (0, utils_1.getDefinitionKey)(actionInMenuActionProperty['$ref']);
1614
+ const actionInMenuActionDefinition = appSchema.definitions[actionInMenuActionPropertyKey];
1615
+ const key = (0, utils_1.getDefinitionKey)(actionInMenuActionDefinition?.$ref ?? actionInMenuActionProperty['$ref']);
1616
+ const importMenuActionParams = {
1617
+ ...importActionParams,
1618
+ actionsInConfig: menuAction[ux_specification_types_1.PropertyName.actions],
1619
+ actionKey: action
1620
+ };
1621
+ importActionToConfigurationObject(importMenuActionParams, key);
1622
+ }
1623
+ (0, common_1.removeEmptyStructure)(actionsInConfig, actionKey);
1624
+ }
1625
+ /**
1626
+ * Determines the strategy type for action settings based on the provided data type and action type.
1627
+ *
1628
+ * @param {string} [dataType=''] - The data type associated with the action settings. Defaults to an empty string.
1629
+ * @param {string} [actionType=''] - The action type within the context of the action settings. Defaults to an empty string.
1630
+ * @returns {DataFieldStrategyTypes} The corresponding strategy type for the given data type and action type.
1631
+ */
1632
+ function determineActionStrategyType(dataType = '', actionType = '') {
1633
+ const key = `${dataType}${actionType}`;
1634
+ return strategyTypeMap.get(key) || "com.sap.vocabularies.UI.v1.DataFieldForAction" /* UIAnnotationTypes.DataFieldForAction */;
1635
+ }
1335
1636
  /**
1336
1637
  * Imports the action settings of a specified reference based on the given parameters.
1337
1638
  *
1338
1639
  * @param {object} importActionParams - The parameters required for importing action settings.
1339
1640
  * @param {object} importActionParams.actionPropertyDefinition - The action property definition containing the $ref to the reference.
1340
1641
  * @param {object} importActionParams.appSchema - The application schema containing definitions and other related metadata.
1341
- * @returns {void} This function does not return a value.
1342
1642
  */
1343
1643
  function importActionSettingsOfReference(importActionParams) {
1344
1644
  const { actionPropertyDefinition, appSchema } = importActionParams;
1345
1645
  const definitionKey = (0, utils_1.getDefinitionKey)(actionPropertyDefinition.$ref);
1346
1646
  const definitionOfReference = appSchema.definitions[definitionKey];
1347
- const actionType = definitionOfReference['dataType'];
1348
- if (actionType === exports.DATA_FIELD_FOR_ACTION_GROUP) {
1349
- importGroupActionSettingsOfReference(importActionParams, definitionOfReference);
1647
+ const dataType = definitionOfReference['dataType'];
1648
+ const actionType = actionPropertyDefinition[ACTION_TYPE];
1649
+ if (actionType === ux_specification_types_1.ActionType.CustomMenu) {
1650
+ importManifestBasedActionMenuSettingsOfReference(importActionParams, definitionOfReference);
1651
+ }
1652
+ else if (dataType === exports.DATA_FIELD_FOR_ACTION_GROUP) {
1653
+ /* Some action groups (e.g. form group actions) have wrapper definition in the schema, in such cases we need to use the referenced definition. */
1654
+ const definitionOfReferenceKey = (0, utils_1.getDefinitionKey)(definitionOfReference.$ref);
1655
+ if (definitionOfReferenceKey === `ObjectPageFormActionGroup<${definitionKey}>`) {
1656
+ const actualDefinitionKey = (0, utils_1.getDefinitionKey)(definitionOfReference.$ref);
1657
+ const actualAtionGroupDefinition = appSchema.definitions[actualDefinitionKey];
1658
+ importGroupActionSettingsOfReference(importActionParams, actualAtionGroupDefinition);
1659
+ }
1660
+ else {
1661
+ importGroupActionSettingsOfReference(importActionParams, definitionOfReference);
1662
+ }
1350
1663
  }
1351
1664
  else {
1352
1665
  importSingleActionSettingsOfReference(importActionParams, definitionOfReference);
@@ -1372,7 +1685,7 @@ function addCustomFieldDefinition(appSchema, v4Page, fieldGroupInManifest, logge
1372
1685
  const configId = fieldGroupInManifest.replace(/::/g, '#');
1373
1686
  const fields = v4Page.options?.settings?.controlConfiguration?.[configId]?.['fields'];
1374
1687
  if (fields) {
1375
- sortedFieldsArray = addExtensionToArray(fields, sortedFieldsArray, customFieldDefinitionName, 'template', logger);
1688
+ sortedFieldsArray = addExtensionToArray(fields, sortedFieldsArray, customFieldDefinitionName, ux_specification_types_1.TemplatePropertyName.Template, logger);
1376
1689
  }
1377
1690
  // Adjust propertyIndex
1378
1691
  if (sortedFieldsArray) {