@sapui5/sap.fe.core 1.141.2 → 1.142.1

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 (207) hide show
  1. package/package.json +1 -1
  2. package/src/sap/fe/core/.library +4 -1
  3. package/src/sap/fe/core/ActionRuntime.js +48 -23
  4. package/src/sap/fe/core/ActionRuntime.ts +61 -35
  5. package/src/sap/fe/core/AppComponent.js +76 -6
  6. package/src/sap/fe/core/AppComponent.ts +94 -8
  7. package/src/sap/fe/core/AppStateHandler.js +9 -8
  8. package/src/sap/fe/core/AppStateHandler.ts +13 -9
  9. package/src/sap/fe/core/BaseController.js +8 -5
  10. package/src/sap/fe/core/BaseController.ts +6 -1
  11. package/src/sap/fe/core/CommonUtils.js +4 -123
  12. package/src/sap/fe/core/CommonUtils.ts +3 -172
  13. package/src/sap/fe/core/ExtensionAPI.js +3 -10
  14. package/src/sap/fe/core/ExtensionAPI.ts +2 -14
  15. package/src/sap/fe/core/PageController.js +64 -43
  16. package/src/sap/fe/core/PageController.ts +62 -47
  17. package/src/sap/fe/core/TemplateComponent.js +20 -1
  18. package/src/sap/fe/core/TemplateComponent.ts +24 -2
  19. package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +37 -24
  20. package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +47 -31
  21. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.js +1 -1
  22. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.ts +4 -0
  23. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.js +4 -1
  24. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.ts +3 -0
  25. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.js +4 -1
  26. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.ts +4 -0
  27. package/src/sap/fe/core/controllerextensions/BaseControllerExtension.js +7 -5
  28. package/src/sap/fe/core/controllerextensions/BaseControllerExtension.ts +22 -2
  29. package/src/sap/fe/core/controllerextensions/CollaborativeDraft.js +82 -39
  30. package/src/sap/fe/core/controllerextensions/CollaborativeDraft.ts +91 -54
  31. package/src/sap/fe/core/controllerextensions/EditFlow.js +25 -3
  32. package/src/sap/fe/core/controllerextensions/EditFlow.ts +27 -3
  33. package/src/sap/fe/core/controllerextensions/InlineEditFlow.js +9 -7
  34. package/src/sap/fe/core/controllerextensions/InlineEditFlow.ts +17 -5
  35. package/src/sap/fe/core/controllerextensions/InternalRouting.js +37 -18
  36. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +49 -17
  37. package/src/sap/fe/core/controllerextensions/KPIManagement.js +30 -15
  38. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +32 -14
  39. package/src/sap/fe/core/controllerextensions/MessageHandler.js +9 -10
  40. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +8 -9
  41. package/src/sap/fe/core/controllerextensions/Paginator.js +2 -2
  42. package/src/sap/fe/core/controllerextensions/Paginator.ts +1 -1
  43. package/src/sap/fe/core/controllerextensions/Placeholder.js +10 -2
  44. package/src/sap/fe/core/controllerextensions/Placeholder.ts +5 -1
  45. package/src/sap/fe/core/controllerextensions/Recommendations.js +3 -3
  46. package/src/sap/fe/core/controllerextensions/Recommendations.ts +2 -2
  47. package/src/sap/fe/core/controllerextensions/Routing.js +9 -5
  48. package/src/sap/fe/core/controllerextensions/Routing.ts +7 -7
  49. package/src/sap/fe/core/controllerextensions/Share.js +5 -5
  50. package/src/sap/fe/core/controllerextensions/Share.ts +4 -4
  51. package/src/sap/fe/core/controllerextensions/SideEffects.js +1 -1
  52. package/src/sap/fe/core/controllerextensions/SideEffects.ts +17 -2
  53. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.js +2 -2
  54. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.ts +1 -1
  55. package/src/sap/fe/core/controllerextensions/editFlow/NotApplicableContextDialog.js +3 -3
  56. package/src/sap/fe/core/controllerextensions/editFlow/NotApplicableContextDialog.tsx +3 -2
  57. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +33 -11
  58. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +45 -14
  59. package/src/sap/fe/core/controllerextensions/editFlow/draft.js +37 -3
  60. package/src/sap/fe/core/controllerextensions/editFlow/draft.ts +41 -8
  61. package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.js +10 -4
  62. package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.ts +6 -1
  63. package/src/sap/fe/core/controllerextensions/editFlow/operations/ODataOperation.js +7 -7
  64. package/src/sap/fe/core/controllerextensions/editFlow/operations/ODataOperation.ts +6 -5
  65. package/src/sap/fe/core/controllerextensions/editFlow/operations/ODataStrictHandling.js +2 -2
  66. package/src/sap/fe/core/controllerextensions/editFlow/operations/ODataStrictHandling.ts +1 -1
  67. package/src/sap/fe/core/controllerextensions/editFlow/operations/OperationParameters.js +2 -1
  68. package/src/sap/fe/core/controllerextensions/editFlow/operations/OperationParameters.ts +1 -0
  69. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +10 -6
  70. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.ts +6 -5
  71. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +11 -9
  72. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.ts +22 -9
  73. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.js +9 -4
  74. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.tsx +10 -4
  75. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.js +31 -2
  76. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.tsx +34 -1
  77. package/src/sap/fe/core/converters/ManifestSettings.js +7 -1
  78. package/src/sap/fe/core/converters/ManifestSettings.ts +37 -0
  79. package/src/sap/fe/core/converters/ManifestWrapper.js +29 -9
  80. package/src/sap/fe/core/converters/ManifestWrapper.ts +29 -11
  81. package/src/sap/fe/core/converters/annotations/DataField.js +46 -19
  82. package/src/sap/fe/core/converters/annotations/DataField.ts +93 -19
  83. package/src/sap/fe/core/converters/common/AnnotationConverter.js +88 -35
  84. package/src/sap/fe/core/converters/controls/Common/Action.js +57 -20
  85. package/src/sap/fe/core/converters/controls/Common/Action.ts +71 -21
  86. package/src/sap/fe/core/converters/controls/Common/Chart.js +13 -3
  87. package/src/sap/fe/core/converters/controls/Common/Chart.ts +20 -4
  88. package/src/sap/fe/core/converters/controls/Common/Form.js +18 -3
  89. package/src/sap/fe/core/converters/controls/Common/Form.ts +23 -1
  90. package/src/sap/fe/core/converters/controls/Common/Table.js +89 -57
  91. package/src/sap/fe/core/converters/controls/Common/Table.ts +110 -56
  92. package/src/sap/fe/core/converters/controls/Common/filter/FilterRestrictions.js +243 -0
  93. package/src/sap/fe/core/converters/controls/Common/filter/FilterRestrictions.ts +309 -0
  94. package/src/sap/fe/core/converters/controls/Common/table/Columns.js +142 -58
  95. package/src/sap/fe/core/converters/controls/Common/table/Columns.ts +172 -78
  96. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +12 -18
  97. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +13 -27
  98. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +7 -16
  99. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +6 -17
  100. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +16 -5
  101. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +16 -5
  102. package/src/sap/fe/core/converters/helpers/Aggregation.js +12 -2
  103. package/src/sap/fe/core/converters/helpers/Aggregation.ts +11 -1
  104. package/src/sap/fe/core/converters/helpers/DataFieldHelper.js +27 -3
  105. package/src/sap/fe/core/converters/helpers/DataFieldHelper.ts +28 -1
  106. package/src/sap/fe/core/converters/helpers/ID.js +3 -1
  107. package/src/sap/fe/core/converters/helpers/ID.ts +1 -0
  108. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +5 -2
  109. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +7 -1
  110. package/src/sap/fe/core/converters/templates/ListReportConverter.js +11 -3
  111. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +12 -4
  112. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +19 -8
  113. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +18 -7
  114. package/src/sap/fe/core/designtime/AnnotationBasedChanges.js +8 -3
  115. package/src/sap/fe/core/designtime/AnnotationBasedChanges.ts +7 -2
  116. package/src/sap/fe/core/formatters/FPMFormatter.js +2 -2
  117. package/src/sap/fe/core/formatters/FPMFormatter.ts +1 -1
  118. package/src/sap/fe/core/fpm/Component.js +8 -1
  119. package/src/sap/fe/core/fpm/Component.ts +8 -0
  120. package/src/sap/fe/core/fpm/manifest.json +1 -1
  121. package/src/sap/fe/core/helpers/AppStartupHelper.js +79 -25
  122. package/src/sap/fe/core/helpers/AppStartupHelper.ts +91 -32
  123. package/src/sap/fe/core/helpers/ManifestHelper.js +6 -3
  124. package/src/sap/fe/core/helpers/ManifestHelper.ts +3 -0
  125. package/src/sap/fe/core/helpers/MetaModelFunction.js +12 -3
  126. package/src/sap/fe/core/helpers/MetaModelFunction.ts +11 -3
  127. package/src/sap/fe/core/helpers/ModelHelper.js +48 -9
  128. package/src/sap/fe/core/helpers/ModelHelper.ts +55 -10
  129. package/src/sap/fe/core/helpers/TypeGuards.js +12 -2
  130. package/src/sap/fe/core/helpers/TypeGuards.ts +10 -1
  131. package/src/sap/fe/core/helpers/WebSocket.js +6 -7
  132. package/src/sap/fe/core/helpers/WebSocket.ts +10 -6
  133. package/src/sap/fe/core/library.js +30 -3
  134. package/src/sap/fe/core/library.ts +28 -1
  135. package/src/sap/fe/core/messagebundle.properties +8 -1
  136. package/src/sap/fe/core/messagebundle_ar.properties +7 -0
  137. package/src/sap/fe/core/messagebundle_bg.properties +10 -3
  138. package/src/sap/fe/core/messagebundle_ca.properties +7 -0
  139. package/src/sap/fe/core/messagebundle_cnr.properties +7 -0
  140. package/src/sap/fe/core/messagebundle_cs.properties +7 -0
  141. package/src/sap/fe/core/messagebundle_cy.properties +8 -1
  142. package/src/sap/fe/core/messagebundle_da.properties +7 -0
  143. package/src/sap/fe/core/messagebundle_de.properties +7 -0
  144. package/src/sap/fe/core/messagebundle_el.properties +7 -0
  145. package/src/sap/fe/core/messagebundle_en.properties +8 -1
  146. package/src/sap/fe/core/messagebundle_en_GB.properties +7 -0
  147. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +5 -0
  148. package/src/sap/fe/core/messagebundle_es.properties +8 -1
  149. package/src/sap/fe/core/messagebundle_es_MX.properties +7 -0
  150. package/src/sap/fe/core/messagebundle_et.properties +7 -0
  151. package/src/sap/fe/core/messagebundle_fi.properties +7 -0
  152. package/src/sap/fe/core/messagebundle_fr.properties +16 -9
  153. package/src/sap/fe/core/messagebundle_fr_CA.properties +7 -0
  154. package/src/sap/fe/core/messagebundle_hi.properties +8 -1
  155. package/src/sap/fe/core/messagebundle_hr.properties +7 -0
  156. package/src/sap/fe/core/messagebundle_hu.properties +7 -0
  157. package/src/sap/fe/core/messagebundle_id.properties +7 -0
  158. package/src/sap/fe/core/messagebundle_it.properties +7 -0
  159. package/src/sap/fe/core/messagebundle_iw.properties +7 -0
  160. package/src/sap/fe/core/messagebundle_ja.properties +8 -1
  161. package/src/sap/fe/core/messagebundle_kk.properties +7 -0
  162. package/src/sap/fe/core/messagebundle_ko.properties +7 -0
  163. package/src/sap/fe/core/messagebundle_lt.properties +7 -0
  164. package/src/sap/fe/core/messagebundle_lv.properties +7 -0
  165. package/src/sap/fe/core/messagebundle_mk.properties +7 -0
  166. package/src/sap/fe/core/messagebundle_ms.properties +7 -0
  167. package/src/sap/fe/core/messagebundle_nl.properties +7 -0
  168. package/src/sap/fe/core/messagebundle_no.properties +7 -0
  169. package/src/sap/fe/core/messagebundle_pl.properties +7 -0
  170. package/src/sap/fe/core/messagebundle_pt.properties +7 -0
  171. package/src/sap/fe/core/messagebundle_pt_PT.properties +7 -0
  172. package/src/sap/fe/core/messagebundle_ro.properties +7 -0
  173. package/src/sap/fe/core/messagebundle_ru.properties +7 -0
  174. package/src/sap/fe/core/messagebundle_sh.properties +7 -0
  175. package/src/sap/fe/core/messagebundle_sk.properties +7 -0
  176. package/src/sap/fe/core/messagebundle_sl.properties +7 -0
  177. package/src/sap/fe/core/messagebundle_sr.properties +7 -0
  178. package/src/sap/fe/core/messagebundle_sv.properties +7 -0
  179. package/src/sap/fe/core/messagebundle_th.properties +7 -0
  180. package/src/sap/fe/core/messagebundle_tr.properties +7 -0
  181. package/src/sap/fe/core/messagebundle_uk.properties +7 -0
  182. package/src/sap/fe/core/messagebundle_vi.properties +7 -0
  183. package/src/sap/fe/core/messagebundle_zh_CN.properties +8 -1
  184. package/src/sap/fe/core/messagebundle_zh_TW.properties +7 -0
  185. package/src/sap/fe/core/rootView/Fcl.controller.js +21 -7
  186. package/src/sap/fe/core/rootView/Fcl.controller.ts +28 -6
  187. package/src/sap/fe/core/rootView/RootViewBaseController.js +96 -88
  188. package/src/sap/fe/core/rootView/RootViewBaseController.ts +106 -96
  189. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +14 -10
  190. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +15 -10
  191. package/src/sap/fe/core/services/RoutingServiceFactory.js +16 -7
  192. package/src/sap/fe/core/services/RoutingServiceFactory.ts +23 -10
  193. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +9 -7
  194. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +13 -8
  195. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +62 -6
  196. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +74 -11
  197. package/src/sap/fe/core/services/collaborativeDraftServiceFactory.js +33 -15
  198. package/src/sap/fe/core/services/collaborativeDraftServiceFactory.ts +31 -11
  199. package/src/sap/fe/core/templating/DisplayModeFormatter.js +4 -5
  200. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +4 -6
  201. package/src/sap/fe/core/templating/UIFormatters.js +17 -2
  202. package/src/sap/fe/core/templating/UIFormatters.ts +25 -1
  203. package/src/sap/fe/core/types/sap.fe.core-auto-ext.d.js +10 -0
  204. package/src/sap/fe/core/types/sap.fe.core-auto-ext.d.ts +369 -0
  205. package/src/sap/fe/core/types/sap.fe.core-manual-ext.d.js +9 -0
  206. package/src/sap/fe/core/types/sap.fe.core-manual-ext.d.ts +49 -0
  207. package/ui5.yaml +2 -0
@@ -28,6 +28,7 @@ import {
28
28
  getExpressionFromAnnotation,
29
29
  ifElse,
30
30
  isConstant,
31
+ isExpressionStaticallyResolvable,
31
32
  not,
32
33
  or,
33
34
  pathInModel,
@@ -50,6 +51,7 @@ import type {
50
51
  } from "sap/fe/core/converters/controls/Common/Action";
51
52
  import {
52
53
  addCollaborationCondition,
54
+ addSeparators,
53
55
  dataFieldIsCopyAction,
54
56
  getActionsFromManifest,
55
57
  getAnnotationMenuActionItems,
@@ -141,6 +143,9 @@ import {
141
143
  isInDisplayMode
142
144
  } from "./table/StandardActions";
143
145
 
146
+ import type { EntityTypeAnnotations_Aggregation } from "@sap-ux/vocabularies-types/vocabularies/Aggregation_Edm";
147
+ import type { EntityTypeAnnotations_Hierarchy } from "@sap-ux/vocabularies-types/vocabularies/Hierarchy_Edm";
148
+
144
149
  type UploadTableSettings = {
145
150
  stream: string;
146
151
  fileName?: string;
@@ -380,8 +385,6 @@ export function getTableActions(
380
385
  navigationSettings?: NavigationSettingsConfiguration
381
386
  ): CombinedAction {
382
387
  // 1. Get actions from annotations
383
- const isCollaborationEnabled = ModelHelper.isCollaborationDraftSupportedFromConverterContext(converterContext);
384
-
385
388
  const tableActions = getTableAnnotationActions(lineItemAnnotation, visualizationPath, converterContext);
386
389
  // 2. Get actions from manifest
387
390
  const manifestActions = getActionsFromManifest(
@@ -438,7 +441,9 @@ export function getTableActions(
438
441
  position: OverrideType.overwrite,
439
442
  menu: OverrideType.overwrite,
440
443
  priority: OverrideType.overwrite,
441
- group: OverrideType.overwrite
444
+ group: OverrideType.overwrite,
445
+ overflowGroup: OverrideType.overwrite,
446
+ disableStrictHandling: OverrideType.overwrite
442
447
  };
443
448
  // 3. Get all annotation menu items
444
449
  const annotationMenuActionItems = getAnnotationMenuActionItems(annotationActions);
@@ -457,12 +462,16 @@ export function getTableActions(
457
462
  prepareMenuActions(actions, overwrittenMenuActionItems);
458
463
  // 8. Remove duplicate actions which are menu items
459
464
  actions = removeDuplicateActions(actions);
460
- // 9. Hide menus where all menu items are hidden
461
- actions = getVisibilityEnablementMenuActions(actions);
462
- // 10. Add the collaboration condition for actions other than navigation
463
- if (isCollaborationEnabled) {
465
+ // 9. Add the collaboration condition for actions other than navigation
466
+ if (ModelHelper.isCollaborationDraftSupportedFromConverterContext(converterContext)) {
464
467
  addCollaborationCondition(actions);
465
468
  }
469
+ // 10. Hide menus where all menu items are hidden
470
+ actions = getVisibilityEnablementMenuActions(actions);
471
+ // 11. Add separators based on actionGroups configuration
472
+ const overflowGroupsConfig =
473
+ converterContext.getManifestControlConfiguration<TableManifestConfiguration>(visualizationPath)?.overflowGroups;
474
+ actions = addSeparators(actions, overflowGroupsConfig) as CustomAction[];
466
475
 
467
476
  return {
468
477
  actions: actions,
@@ -973,8 +982,7 @@ function getCurrentEntitySetUpdatablePath(converterContext: ConverterContext<Pag
973
982
  const updatable = restrictions.isUpdatable;
974
983
  const isOnlyDynamicOnCurrentEntity = !isConstant(updatable.expression) && updatable.navigationExpression._type === "Unresolvable";
975
984
  const updatableExpression = entitySet?.annotations.Capabilities?.UpdateRestrictions?.Updatable;
976
- const updatablePropertyPath = isPathAnnotationExpression(updatableExpression) && updatableExpression.path;
977
- return isOnlyDynamicOnCurrentEntity ? (updatablePropertyPath as string) : "";
985
+ return isOnlyDynamicOnCurrentEntity && isPathAnnotationExpression(updatableExpression) ? updatableExpression.path : "";
978
986
  }
979
987
  /**
980
988
  * Method to retrieve all property paths assigned to the Core.OperationAvailable annotation.
@@ -1239,8 +1247,7 @@ export function getSelectionMode(
1239
1247
  visualizationPath: string,
1240
1248
  converterContext: ConverterContext<PageContextPathTarget>,
1241
1249
  isEntitySet: boolean,
1242
- targetCapabilities: TableCapabilityRestriction,
1243
- deleteButtonVisibilityExpression?: BindingToolkitExpression<boolean>,
1250
+ deleteButtonVisibilityExpression: BindingToolkitExpression<boolean>,
1244
1251
  massEditVisibilityExpression: BindingToolkitExpression<boolean> = constant(false),
1245
1252
  cutButtonVisibilityExpression: BindingToolkitExpression<boolean> = constant(false)
1246
1253
  ): string | undefined {
@@ -1248,25 +1255,30 @@ export function getSelectionMode(
1248
1255
  const tableType = tableManifestSettings.tableSettings?.type;
1249
1256
  let selectionMode = tableManifestSettings.tableSettings?.selectionMode;
1250
1257
 
1251
- // The collapse/Expand action of a tree table is a bound action, as a result, a tree table should always have a selection mode to "Multi" when no selectionMode has been set in the manifest
1258
+ // NEW: derive deletable from path expression instead of targetCapabilities.isDeletable
1259
+ let pathDeletableExpression = isPathDeletable(converterContext.getDataModelObjectPath());
1260
+ if (!isExpressionStaticallyResolvable(pathDeletableExpression)) {
1261
+ // dynamic (depends on path/singleton) -> treat as "potentially deletable"
1262
+ pathDeletableExpression = constant(true);
1263
+ }
1264
+ const deletableStaticFalse = isConstant(pathDeletableExpression) && pathDeletableExpression.value === false;
1265
+
1266
+ // TreeTable: default to Multi if not set
1252
1267
  if (tableType === "TreeTable" && !selectionMode) {
1253
1268
  return SelectionMode.Multi;
1254
1269
  }
1255
1270
 
1256
1271
  // If the selection mode is forced to 'None' in the manifest/macro table parameters, we keep it unless here is a delete button
1257
1272
  if (!lineItemAnnotation || selectionMode === SelectionMode.None) {
1258
- if (targetCapabilities.isDeletable && deleteButtonVisibilityExpression) {
1259
- return compileExpression(ifElse(deleteButtonVisibilityExpression, constant(SelectionMode.Multi), constant(SelectionMode.None)));
1260
- }
1261
- return SelectionMode.None;
1273
+ return compileExpression(ifElse(deleteButtonVisibilityExpression, constant(SelectionMode.Multi), constant(SelectionMode.None)));
1262
1274
  }
1263
1275
  if (selectionMode === SelectionMode.ForceMulti) {
1264
1276
  return SelectionMode.Multi;
1265
1277
  } else if (selectionMode === SelectionMode.ForceSingle) {
1266
1278
  return SelectionMode.Single;
1267
1279
  }
1268
- let aHiddenBindingExpressions: BindingToolkitExpression<boolean>[] = [],
1269
- aVisibleBindingExpressions: BindingToolkitExpression<boolean>[] = [];
1280
+ let hiddenBindingExpressions: BindingToolkitExpression<boolean>[] = [],
1281
+ visibleBindingExpressions: BindingToolkitExpression<boolean>[] = [];
1270
1282
  const manifestActions = getActionsFromManifest(
1271
1283
  converterContext.getManifestControlConfiguration<TableManifestConfiguration>(visualizationPath).actions,
1272
1284
  converterContext,
@@ -1279,11 +1291,11 @@ export function getSelectionMode(
1279
1291
  isParentDeletable = isPathDeletable(converterContext.getDataModelObjectPath());
1280
1292
  parentEntitySetDeletable = isParentDeletable ? compileExpression(isParentDeletable, true) : isParentDeletable;
1281
1293
  }
1282
- const bMassEditEnabled: boolean = !isConstant(massEditVisibilityExpression) || massEditVisibilityExpression.value !== false;
1294
+ const massEditEnabled: boolean = !isConstant(massEditVisibilityExpression) || massEditVisibilityExpression.value !== false;
1283
1295
  if (!selectionMode || selectionMode === SelectionMode.Auto) {
1284
1296
  selectionMode = SelectionMode.Multi;
1285
1297
  }
1286
- if (bMassEditEnabled) {
1298
+ if (massEditEnabled) {
1287
1299
  // Override default selection mode when mass edit is visible
1288
1300
  selectionMode = selectionMode === SelectionMode.Single ? SelectionMode.Single : SelectionMode.Multi;
1289
1301
  }
@@ -1293,25 +1305,24 @@ export function getSelectionMode(
1293
1305
  ) {
1294
1306
  return selectionMode;
1295
1307
  }
1296
- aHiddenBindingExpressions = getUIHiddenExpForActionsRequiringContext(
1308
+ hiddenBindingExpressions = getUIHiddenExpForActionsRequiringContext(
1297
1309
  lineItemAnnotation,
1298
1310
  converterContext.getEntityType(),
1299
1311
  converterContext.getDataModelObjectPath()
1300
1312
  );
1301
- aVisibleBindingExpressions = getVisibleExpForCustomActionsRequiringContext(manifestActions.actions);
1313
+ visibleBindingExpressions = getVisibleExpForCustomActionsRequiringContext(manifestActions.actions);
1302
1314
  // No action requiring a context:
1303
1315
  if (
1304
- aHiddenBindingExpressions.length === 0 &&
1305
- aVisibleBindingExpressions.length === 0 &&
1306
- (cutButtonVisibilityExpression || deleteButtonVisibilityExpression || bMassEditEnabled)
1316
+ hiddenBindingExpressions.length === 0 &&
1317
+ visibleBindingExpressions.length === 0 &&
1318
+ (cutButtonVisibilityExpression || deleteButtonVisibilityExpression || massEditEnabled)
1307
1319
  ) {
1308
1320
  if (!isEntitySet) {
1309
- // Example: OP case
1310
- if (targetCapabilities.isDeletable || parentEntitySetDeletable !== "false" || bMassEditEnabled) {
1311
- // Building expression for delete and mass edit
1321
+ // OP case:
1322
+ if (!deletableStaticFalse || parentEntitySetDeletable !== "false" || massEditEnabled) {
1312
1323
  const buttonVisibilityExpression = or(
1313
1324
  cutButtonVisibilityExpression || true,
1314
- deleteButtonVisibilityExpression || true, // default delete visibility as true
1325
+ deleteButtonVisibilityExpression,
1315
1326
  massEditVisibilityExpression
1316
1327
  );
1317
1328
  return compileExpression(
@@ -1322,23 +1333,19 @@ export function getSelectionMode(
1322
1333
  ifElse(cutButtonVisibilityExpression, constant(SelectionMode.Single), constant(SelectionMode.None))
1323
1334
  );
1324
1335
  }
1325
- // EntitySet deletable:
1326
- } else if (bMassEditEnabled) {
1327
- // example: LR scenario
1328
- return selectionMode;
1329
- } else if (targetCapabilities.isDeletable && deleteButtonVisibilityExpression) {
1330
- return compileExpression(ifElse(deleteButtonVisibilityExpression, constant(selectionMode), constant(SelectionMode.None)));
1331
- // EntitySet not deletable:
1332
1336
  } else {
1333
- return SelectionMode.None;
1337
+ // EntitySet case:
1338
+ return compileExpression(
1339
+ ifElse(or(massEditEnabled, deleteButtonVisibilityExpression), constant(selectionMode), constant(SelectionMode.None))
1340
+ );
1334
1341
  }
1335
1342
  // There are actions requiring a context:
1336
1343
  } else if (!isEntitySet) {
1337
- // Example: OP case
1338
- if (targetCapabilities.isDeletable || parentEntitySetDeletable !== "false" || bMassEditEnabled) {
1344
+ // OP case:
1345
+ if (!deletableStaticFalse || parentEntitySetDeletable !== "false" || massEditEnabled) {
1339
1346
  // Use selectionMode in edit mode if delete is enabled or mass edit is visible
1340
1347
  const editModebuttonVisibilityExpression = ifElse(
1341
- bMassEditEnabled && !targetCapabilities.isDeletable,
1348
+ massEditEnabled && deletableStaticFalse,
1342
1349
  massEditVisibilityExpression,
1343
1350
  constant(true)
1344
1351
  );
@@ -1347,7 +1354,7 @@ export function getSelectionMode(
1347
1354
  and(UI.IsEditable, editModebuttonVisibilityExpression),
1348
1355
  constant(selectionMode),
1349
1356
  ifElse(
1350
- or(...aHiddenBindingExpressions.concat(aVisibleBindingExpressions)),
1357
+ or(...hiddenBindingExpressions.concat(visibleBindingExpressions)),
1351
1358
  constant(selectionMode),
1352
1359
  constant(SelectionMode.None)
1353
1360
  )
@@ -1356,23 +1363,23 @@ export function getSelectionMode(
1356
1363
  } else {
1357
1364
  return compileExpression(
1358
1365
  ifElse(
1359
- or(...aHiddenBindingExpressions.concat(aVisibleBindingExpressions)),
1366
+ or(...hiddenBindingExpressions.concat(visibleBindingExpressions)),
1360
1367
  constant(selectionMode),
1361
1368
  constant(SelectionMode.None)
1362
1369
  )
1363
1370
  );
1364
1371
  }
1365
- //EntitySet deletable:
1366
- } else if (targetCapabilities.isDeletable || bMassEditEnabled) {
1367
- // Example: LR scenario
1368
- return selectionMode;
1369
- //EntitySet not deletable:
1372
+ // EntitySet
1370
1373
  } else {
1371
1374
  return compileExpression(
1372
1375
  ifElse(
1373
- or(...aHiddenBindingExpressions.concat(aVisibleBindingExpressions), massEditVisibilityExpression),
1376
+ or(massEditEnabled, deleteButtonVisibilityExpression),
1374
1377
  constant(selectionMode),
1375
- constant(SelectionMode.None)
1378
+ ifElse(
1379
+ or(...hiddenBindingExpressions.concat(visibleBindingExpressions), massEditVisibilityExpression),
1380
+ constant(selectionMode),
1381
+ constant(SelectionMode.None)
1382
+ )
1376
1383
  )
1377
1384
  );
1378
1385
  }
@@ -1469,6 +1476,7 @@ function getDataFieldAnnotationAction(
1469
1476
  text: dataField.Label?.toString(),
1470
1477
  visible: compileExpression(visibleExpression(dataField, converterContext)),
1471
1478
  isAIOperation: isMenuAIOperation(dataField.Actions) === true || undefined,
1479
+ isNavigable: true,
1472
1480
  menu: dataField.Actions.map((action) => getDataFieldAnnotationAction(action, converterContext))
1473
1481
  } as AnnotationActionGroup;
1474
1482
  default:
@@ -2115,14 +2123,12 @@ export function getTableAnnotationConfiguration(
2115
2123
  const hasAbsolutePath = navigationPropertyPath.length === 0;
2116
2124
  const p13nMode = getP13nMode(visualizationPath, converterContext, tableManifestConfiguration);
2117
2125
  const id = navigationPropertyPath ? getTableID(visualizationPath) : getTableID(converterContext.getContextPath(), "LineItem");
2118
- const targetCapabilities = getCapabilityRestriction(converterContext);
2119
2126
  const navigationTargetPath = getNavigationTargetPath(converterContext, navigationPropertyPath);
2120
2127
  const selectionMode = getSelectionMode(
2121
2128
  lineItemAnnotation,
2122
2129
  visualizationPath,
2123
2130
  converterContext,
2124
2131
  hasAbsolutePath,
2125
- targetCapabilities,
2126
2132
  standardActionsConfiguration.deleteButtonVisibilityExpression,
2127
2133
  standardActionsConfiguration.massEditButtonVisibilityExpression,
2128
2134
  standardActionsConfiguration.cutButtonVisibilityExpression
@@ -2422,10 +2428,13 @@ function _useEnabledExpression(dataField: DataFieldForActionTypes, sEntityType:
2422
2428
  function updateTreeTableManifestConfiguration(
2423
2429
  tableConfiguration: TableControlConfiguration,
2424
2430
  tableSettings: TableManifestSettingsConfiguration,
2425
- converterContext: ConverterContext
2431
+ converterContext: ConverterContext,
2432
+ lineItemAnnotation: LineItem | undefined
2426
2433
  ): void {
2427
2434
  const dataModelObjectPath = converterContext.getDataModelObjectPath();
2428
- tableConfiguration.hierarchyQualifier = tableSettings.hierarchyQualifier;
2435
+ const entityType = converterContext.getAnnotationEntityType(lineItemAnnotation);
2436
+
2437
+ tableConfiguration.hierarchyQualifier = getHierarchyQualifier(entityType, tableSettings);
2429
2438
  const hierarchyParentNavigationPropertyPath = getHierarchyParentNavigationPropertyPath(
2430
2439
  dataModelObjectPath,
2431
2440
  tableConfiguration.hierarchyQualifier!
@@ -2493,6 +2502,31 @@ export function getCustomFunctionInfo(
2493
2502
  return { moduleName, methodName };
2494
2503
  }
2495
2504
 
2505
+ /**
2506
+ * Gets the hierarchy qualifier from the manifest or the annotations.
2507
+ * @param entityType The entity type of the table
2508
+ * @param tableSettings The table configuration
2509
+ * @returns the hierarchy qualifier or undefined if not found
2510
+ */
2511
+
2512
+ function getHierarchyQualifier(entityType: EntityType, tableSettings: TableManifestSettingsConfiguration): string | undefined {
2513
+ if (tableSettings.hierarchyQualifier) {
2514
+ return tableSettings.hierarchyQualifier;
2515
+ }
2516
+ const aggregationAnnotation = entityType.annotations?.Aggregation as EntityTypeAnnotations_Aggregation & { _keys?: string[] };
2517
+ const hierarchyAnnotation = entityType.annotations?.Hierarchy as EntityTypeAnnotations_Hierarchy & { _keys?: string[] };
2518
+ // We only check the hierarchyQualifier from the manifest when the tree table is specifically set, otherwise we get it from the annotations
2519
+ // if both annotations have the same qualifier, use it
2520
+ // If there is no qualifier or different qualifiers, the hierarchyQualifier remains undefined
2521
+ // Note: In case of multiple hierarchies with the same qualifier, the first one found will be used
2522
+ const qualifiedName = hierarchyAnnotation?._keys?.find(
2523
+ (key) => key.includes("RecursiveHierarchy#") && aggregationAnnotation?._keys?.includes(key)
2524
+ );
2525
+ if (qualifiedName) {
2526
+ return (hierarchyAnnotation as Record<string, { qualifier?: string }>)[qualifiedName]?.qualifier;
2527
+ }
2528
+ }
2529
+
2496
2530
  /**
2497
2531
  * Retrieve the table control configuration optimistic batch information.
2498
2532
  * @param tableManifestSettings The table configuration
@@ -2595,7 +2629,7 @@ export function getTableManifestConfiguration(
2595
2629
  : {};
2596
2630
  const customValidationFunction = tableSettings.creationMode?.customValidationFunction;
2597
2631
  const exportRequestSize = tableSettings.exportRequestSize;
2598
- const tableType = getTableType(converterContext, tableManifestSettings);
2632
+ const tableType = getTableType(converterContext, tableManifestSettings, lineItemAnnotation);
2599
2633
  const analyticalConfiguration = tableSettings.analyticalConfiguration;
2600
2634
  // By default, paste is enabled on an ObjectPage and on a ListReport with a draft TreeTable
2601
2635
  const enablePaste =
@@ -2678,7 +2712,7 @@ export function getTableManifestConfiguration(
2678
2712
  tableConfiguration.selectionChange = tableSettings.selectionChange;
2679
2713
  tableConfiguration.rowPress = tableSettings.rowPress;
2680
2714
  if (tableType === "TreeTable") {
2681
- updateTreeTableManifestConfiguration(tableConfiguration, tableSettings, converterContext);
2715
+ updateTreeTableManifestConfiguration(tableConfiguration, tableSettings, converterContext, lineItemAnnotation);
2682
2716
  }
2683
2717
 
2684
2718
  if (tableSettings.headerVisible !== undefined) {
@@ -2694,12 +2728,32 @@ export function getTableManifestConfiguration(
2694
2728
 
2695
2729
  function getTableType(
2696
2730
  converterContext: ConverterContext<PageContextPathTarget>,
2697
- tableManifestSettings?: TableManifestConfiguration
2731
+ tableManifestSettings?: TableManifestConfiguration,
2732
+ lineItemAnnotation?: LineItem
2698
2733
  ): TableType {
2699
2734
  if (tableManifestSettings?.tableSettings?.type) {
2700
2735
  // in case the application specified a table type we will use this one
2701
2736
  return tableManifestSettings.tableSettings.type;
2702
2737
  }
2738
+ const entityType = converterContext.getAnnotationEntityType(lineItemAnnotation);
2739
+ const aggregationHelper = new AggregationHelper(entityType, converterContext);
2740
+ const requiredAllowedTransformations = ["filter", "identity", "orderby", "skip", "top", "groupby", "aggregate", "concat"];
2741
+
2742
+ if (
2743
+ aggregationHelper.isAnalyticsSupported() &&
2744
+ requiredAllowedTransformations.every(
2745
+ (transformation: string) => aggregationHelper.getAllowedTransformations()?.includes(transformation)
2746
+ )
2747
+ ) {
2748
+ return "AnalyticalTable";
2749
+ }
2750
+
2751
+ const hierarchyAnnotation = entityType.annotations?.Hierarchy as EntityTypeAnnotations_Hierarchy & { _keys?: string[] };
2752
+ const aggregationAnnotation = entityType.annotations?.Aggregation as EntityTypeAnnotations_Aggregation & { _keys?: string[] };
2753
+ if (hierarchyAnnotation?._keys?.some((key) => key.includes("RecursiveHierarchy#") && aggregationAnnotation?._keys?.includes(key))) {
2754
+ // Check if there is at least one RecursiveHierarchy qualifier is present in both hierarchyAnnotation and aggregationAnnotation annotations
2755
+ return "TreeTable";
2756
+ }
2703
2757
 
2704
2758
  // default is the ResponsiveTable
2705
2759
  return "ResponsiveTable";