@sapui5/sap.fe.core 1.121.2 → 1.123.0

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 (241) hide show
  1. package/package.json +1 -1
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/ActionRuntime.js +2 -2
  4. package/src/sap/fe/core/ActionRuntime.ts +1 -2
  5. package/src/sap/fe/core/CommonUtils.js +14 -171
  6. package/src/sap/fe/core/CommonUtils.ts +15 -221
  7. package/src/sap/fe/core/PageController.js +13 -1
  8. package/src/sap/fe/core/PageController.ts +16 -0
  9. package/src/sap/fe/core/TemplateComponent.js +6 -1
  10. package/src/sap/fe/core/TemplateComponent.ts +8 -0
  11. package/src/sap/fe/core/UIProvider.js +23 -0
  12. package/src/sap/fe/core/UIProvider.ts +38 -0
  13. package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.js +97 -43
  14. package/src/sap/fe/core/buildingBlocks/BuildingBlockBase.ts +120 -50
  15. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.js +6 -3
  16. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockSupport.ts +12 -18
  17. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.js +2 -2
  18. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplateProcessor.ts +1 -1
  19. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.js +1 -1
  20. package/src/sap/fe/core/buildingBlocks/templating/BuildingBlockTemplatingBase.ts +4 -3
  21. package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.js +1 -1
  22. package/src/sap/fe/core/buildingBlocks/templating/RuntimeBuildingBlockFragment.ts +1 -0
  23. package/src/sap/fe/core/controllerextensions/BaseControllerExtension.js +42 -1
  24. package/src/sap/fe/core/controllerextensions/BaseControllerExtension.ts +40 -0
  25. package/src/sap/fe/core/controllerextensions/CollaborativeDraft.js +5 -2
  26. package/src/sap/fe/core/controllerextensions/CollaborativeDraft.ts +5 -3
  27. package/src/sap/fe/core/controllerextensions/EditFlow.js +151 -60
  28. package/src/sap/fe/core/controllerextensions/EditFlow.ts +165 -68
  29. package/src/sap/fe/core/controllerextensions/HookSupport.js +32 -14
  30. package/src/sap/fe/core/controllerextensions/HookSupport.ts +35 -14
  31. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +5 -17
  32. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +0 -12
  33. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +6 -6
  34. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +15 -10
  35. package/src/sap/fe/core/controllerextensions/InternalRouting.js +108 -287
  36. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +117 -309
  37. package/src/sap/fe/core/controllerextensions/KPIManagement.js +2 -2
  38. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +6 -2
  39. package/src/sap/fe/core/controllerextensions/MessageHandler.js +2 -2
  40. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +1 -1
  41. package/src/sap/fe/core/controllerextensions/PageReady.js +6 -6
  42. package/src/sap/fe/core/controllerextensions/PageReady.ts +5 -4
  43. package/src/sap/fe/core/controllerextensions/Paginator.js +17 -110
  44. package/src/sap/fe/core/controllerextensions/Paginator.ts +13 -130
  45. package/src/sap/fe/core/controllerextensions/Placeholder.js +3 -3
  46. package/src/sap/fe/core/controllerextensions/Placeholder.ts +1 -2
  47. package/src/sap/fe/core/controllerextensions/Recommendations.js +36 -31
  48. package/src/sap/fe/core/controllerextensions/Recommendations.ts +32 -37
  49. package/src/sap/fe/core/controllerextensions/Share.js +7 -7
  50. package/src/sap/fe/core/controllerextensions/Share.ts +6 -6
  51. package/src/sap/fe/core/controllerextensions/SideEffects.js +52 -6
  52. package/src/sap/fe/core/controllerextensions/SideEffects.ts +56 -4
  53. package/src/sap/fe/core/controllerextensions/ViewState.js +32 -46
  54. package/src/sap/fe/core/controllerextensions/ViewState.ts +24 -31
  55. package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.js +42 -31
  56. package/src/sap/fe/core/controllerextensions/dialog/OperationsDialog.block.tsx +6 -0
  57. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +168 -276
  58. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +182 -310
  59. package/src/sap/fe/core/controllerextensions/editFlow/draft.js +3 -3
  60. package/src/sap/fe/core/controllerextensions/editFlow/draft.ts +2 -2
  61. package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.js +4 -3
  62. package/src/sap/fe/core/controllerextensions/editFlow/draftDataLossPopup.ts +3 -2
  63. package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.js +74 -52
  64. package/src/sap/fe/core/controllerextensions/editFlow/operations/facade.ts +95 -55
  65. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +3 -17
  66. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.ts +10 -23
  67. package/src/sap/fe/core/controllerextensions/recommendations/Telemetry.js +3 -3
  68. package/src/sap/fe/core/controllerextensions/recommendations/Telemetry.ts +2 -2
  69. package/src/sap/fe/core/controllerextensions/routing/ContextPathHelper.js +225 -0
  70. package/src/sap/fe/core/controllerextensions/routing/ContextPathHelper.ts +241 -0
  71. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.js +69 -48
  72. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DraftDataLossDialog.block.tsx +56 -33
  73. package/src/sap/fe/core/controls/FormElementWrapper.js +8 -11
  74. package/src/sap/fe/core/controls/FormElementWrapper.ts +9 -0
  75. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.js +6 -14
  76. package/src/sap/fe/core/controls/Recommendations/ConfirmRecommendationDialog.block.tsx +12 -23
  77. package/src/sap/fe/core/converters/ConverterContext.js +17 -9
  78. package/src/sap/fe/core/converters/ConverterContext.ts +55 -41
  79. package/src/sap/fe/core/converters/ManifestSettings.js +1 -1
  80. package/src/sap/fe/core/converters/ManifestSettings.ts +19 -5
  81. package/src/sap/fe/core/converters/ManifestWrapper.js +14 -4
  82. package/src/sap/fe/core/converters/ManifestWrapper.ts +21 -10
  83. package/src/sap/fe/core/converters/MetaModelConverter.js +402 -383
  84. package/src/sap/fe/core/converters/MetaModelConverter.ts +538 -338
  85. package/src/sap/fe/core/converters/TemplateConverter.js +4 -2
  86. package/src/sap/fe/core/converters/TemplateConverter.ts +18 -13
  87. package/src/sap/fe/core/converters/annotations/DataField.js +30 -28
  88. package/src/sap/fe/core/converters/annotations/DataField.ts +58 -35
  89. package/src/sap/fe/core/converters/common/AnnotationConverter.js +24 -23
  90. package/src/sap/fe/core/converters/controls/Common/Action.js +5 -4
  91. package/src/sap/fe/core/converters/controls/Common/Action.ts +34 -28
  92. package/src/sap/fe/core/converters/controls/Common/Chart.js +37 -33
  93. package/src/sap/fe/core/converters/controls/Common/Chart.ts +64 -46
  94. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +15 -4
  95. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +31 -15
  96. package/src/sap/fe/core/converters/controls/Common/Form.js +6 -4
  97. package/src/sap/fe/core/converters/controls/Common/Form.ts +23 -11
  98. package/src/sap/fe/core/converters/controls/Common/KPI.js +5 -3
  99. package/src/sap/fe/core/converters/controls/Common/KPI.ts +17 -11
  100. package/src/sap/fe/core/converters/controls/Common/Table.js +197 -101
  101. package/src/sap/fe/core/converters/controls/Common/Table.ts +393 -182
  102. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +4 -5
  103. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +38 -27
  104. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +41 -11
  105. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +112 -45
  106. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +7 -7
  107. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +18 -12
  108. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.js +1 -1
  109. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.ts +5 -4
  110. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +1 -1
  111. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +19 -9
  112. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +64 -63
  113. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +109 -100
  114. package/src/sap/fe/core/converters/helpers/Aggregation.js +12 -11
  115. package/src/sap/fe/core/converters/helpers/Aggregation.ts +35 -30
  116. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +4 -1
  117. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +12 -9
  118. package/src/sap/fe/core/converters/helpers/DataFieldHelper.js +1 -1
  119. package/src/sap/fe/core/converters/helpers/DataFieldHelper.ts +1 -1
  120. package/src/sap/fe/core/converters/helpers/ID.js +1 -1
  121. package/src/sap/fe/core/converters/helpers/ID.ts +6 -6
  122. package/src/sap/fe/core/converters/helpers/InsightsHelpers.js +3 -3
  123. package/src/sap/fe/core/converters/helpers/InsightsHelpers.ts +11 -6
  124. package/src/sap/fe/core/converters/helpers/Key.js +2 -2
  125. package/src/sap/fe/core/converters/helpers/Key.ts +4 -4
  126. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.js +1 -1
  127. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.ts +2 -2
  128. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +21 -19
  129. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +43 -31
  130. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +1 -1
  131. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +16 -12
  132. package/src/sap/fe/core/converters/templates/ListReportConverter.js +8 -3
  133. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +41 -21
  134. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +5 -3
  135. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +24 -19
  136. package/src/sap/fe/core/designtime/AppComponent.designtime.js +3 -2
  137. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +2 -1
  138. package/src/sap/fe/core/filter/DraftEditState.fragment.xml +1 -1
  139. package/src/sap/fe/core/formatters/CollaborationFormatter.js +4 -6
  140. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +5 -4
  141. package/src/sap/fe/core/formatters/FPMFormatter.js +5 -13
  142. package/src/sap/fe/core/formatters/FPMFormatter.ts +11 -10
  143. package/src/sap/fe/core/formatters/FiscalFormat.js +1 -1
  144. package/src/sap/fe/core/formatters/FiscalFormat.ts +1 -1
  145. package/src/sap/fe/core/formatters/KPIFormatter.js +4 -7
  146. package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -3
  147. package/src/sap/fe/core/formatters/StandardFormatter.js +4 -7
  148. package/src/sap/fe/core/formatters/StandardFormatter.ts +3 -3
  149. package/src/sap/fe/core/formatters/ValueFormatter.js +35 -6
  150. package/src/sap/fe/core/formatters/ValueFormatter.ts +31 -3
  151. package/src/sap/fe/core/fpm/manifest.json +1 -1
  152. package/src/sap/fe/core/helpers/AppStartupHelper.js +54 -33
  153. package/src/sap/fe/core/helpers/AppStartupHelper.ts +62 -41
  154. package/src/sap/fe/core/helpers/BindingToolkit.js +17 -3
  155. package/src/sap/fe/core/helpers/BindingToolkit.ts +28 -6
  156. package/src/sap/fe/core/helpers/ClassSupport.js +32 -13
  157. package/src/sap/fe/core/helpers/ClassSupport.ts +35 -15
  158. package/src/sap/fe/core/helpers/DeleteHelper.js +71 -61
  159. package/src/sap/fe/core/helpers/DeleteHelper.ts +125 -103
  160. package/src/sap/fe/core/helpers/DraftEditState.js +5 -3
  161. package/src/sap/fe/core/helpers/DraftEditState.ts +3 -1
  162. package/src/sap/fe/core/helpers/FPMHelper.js +43 -46
  163. package/src/sap/fe/core/helpers/FPMHelper.ts +50 -56
  164. package/src/sap/fe/core/helpers/MetaModelFunction.js +77 -53
  165. package/src/sap/fe/core/helpers/MetaModelFunction.ts +78 -57
  166. package/src/sap/fe/core/helpers/ModelHelper.js +10 -4
  167. package/src/sap/fe/core/helpers/ModelHelper.ts +12 -6
  168. package/src/sap/fe/core/helpers/PasteHelper.js +194 -7
  169. package/src/sap/fe/core/helpers/PasteHelper.ts +265 -13
  170. package/src/sap/fe/core/helpers/PromiseKeeper.js +66 -0
  171. package/src/sap/fe/core/helpers/PromiseKeeper.ts +56 -0
  172. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +30 -19
  173. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +34 -22
  174. package/src/sap/fe/core/helpers/StableIdHelper.js +1 -1
  175. package/src/sap/fe/core/helpers/StableIdHelper.ts +7 -2
  176. package/src/sap/fe/core/helpers/StandardRecommendationHelper.js +26 -52
  177. package/src/sap/fe/core/helpers/StandardRecommendationHelper.ts +37 -63
  178. package/src/sap/fe/core/helpers/TitleHelper.js +1 -1
  179. package/src/sap/fe/core/helpers/TitleHelper.ts +17 -14
  180. package/src/sap/fe/core/helpers/TypeGuards.js +27 -3
  181. package/src/sap/fe/core/helpers/TypeGuards.ts +37 -7
  182. package/src/sap/fe/core/jsx-runtime/jsx-xml.js +48 -8
  183. package/src/sap/fe/core/jsx-runtime/jsx-xml.ts +40 -9
  184. package/src/sap/fe/core/library.js +1 -1
  185. package/src/sap/fe/core/messagebundle.properties +5 -2
  186. package/src/sap/fe/core/messagebundle_da.properties +1 -1
  187. package/src/sap/fe/core/messagebundle_en.properties +267 -2
  188. package/src/sap/fe/core/messagebundle_sl.properties +1 -1
  189. package/src/sap/fe/core/operationsHelper.js +2 -1
  190. package/src/sap/fe/core/operationsHelper.ts +1 -0
  191. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +3 -3
  192. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +2 -2
  193. package/src/sap/fe/core/services/NavigationServiceFactory.js +2 -2
  194. package/src/sap/fe/core/services/NavigationServiceFactory.ts +3 -2
  195. package/src/sap/fe/core/services/RoutingServiceFactory.js +27 -14
  196. package/src/sap/fe/core/services/RoutingServiceFactory.ts +27 -14
  197. package/src/sap/fe/core/services/ShellServicesFactory.js +49 -12
  198. package/src/sap/fe/core/services/ShellServicesFactory.ts +62 -13
  199. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +156 -82
  200. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +218 -100
  201. package/src/sap/fe/core/services/TelemetryServiceFactory.js +3 -3
  202. package/src/sap/fe/core/services/TelemetryServiceFactory.ts +6 -6
  203. package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.js +3 -2
  204. package/src/sap/fe/core/services/ValueHelpHistoryServiceFactory.ts +1 -1
  205. package/src/sap/fe/core/services/collaborativeDraftServiceFactory.js +1 -1
  206. package/src/sap/fe/core/services/collaborativeDraftServiceFactory.ts +2 -2
  207. package/src/sap/fe/core/services/view/TemplatingErrorPage.view.xml +1 -1
  208. package/src/sap/fe/core/templating/CommonFormatters.js +6 -3
  209. package/src/sap/fe/core/templating/CommonFormatters.ts +13 -12
  210. package/src/sap/fe/core/templating/CriticalityFormatters.js +2 -2
  211. package/src/sap/fe/core/templating/CriticalityFormatters.ts +37 -14
  212. package/src/sap/fe/core/templating/DataFieldFormatters.js +12 -11
  213. package/src/sap/fe/core/templating/DataFieldFormatters.ts +35 -24
  214. package/src/sap/fe/core/templating/DataModelPathHelper.js +22 -18
  215. package/src/sap/fe/core/templating/DataModelPathHelper.ts +61 -51
  216. package/src/sap/fe/core/templating/DisplayModeFormatter.js +1 -1
  217. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +8 -3
  218. package/src/sap/fe/core/templating/EntityTypeHelper.js +1 -1
  219. package/src/sap/fe/core/templating/EntityTypeHelper.ts +1 -1
  220. package/src/sap/fe/core/templating/FieldControlHelper.js +3 -3
  221. package/src/sap/fe/core/templating/FieldControlHelper.ts +27 -8
  222. package/src/sap/fe/core/templating/FilterHelper.js +13 -10
  223. package/src/sap/fe/core/templating/FilterHelper.ts +80 -46
  224. package/src/sap/fe/core/templating/FilterTemplating.js +1 -1
  225. package/src/sap/fe/core/templating/FilterTemplating.ts +2 -2
  226. package/src/sap/fe/core/templating/PropertyFormatters.js +6 -8
  227. package/src/sap/fe/core/templating/PropertyFormatters.ts +11 -11
  228. package/src/sap/fe/core/templating/PropertyHelper.js +3 -3
  229. package/src/sap/fe/core/templating/PropertyHelper.ts +4 -4
  230. package/src/sap/fe/core/templating/SemanticObjectHelper.js +157 -13
  231. package/src/sap/fe/core/templating/SemanticObjectHelper.ts +182 -16
  232. package/src/sap/fe/core/templating/UIFormatters.js +23 -22
  233. package/src/sap/fe/core/templating/UIFormatters.ts +94 -66
  234. package/src/sap/fe/core/type/DateTimeWithTimezone.js +1 -1
  235. package/src/sap/fe/core/type/DateTimeWithTimezone.ts +2 -2
  236. package/src/sap/fe/core/type/EDM.js +1 -1
  237. package/src/sap/fe/core/type/EDM.ts +2 -2
  238. package/src/sap/fe/core/type/Email.js +1 -1
  239. package/src/sap/fe/core/type/Email.ts +1 -1
  240. package/src/sap/fe/core/type/FiscalDate.js +2 -2
  241. package/src/sap/fe/core/type/FiscalDate.ts +2 -2
@@ -3,11 +3,14 @@ import type PageController from "sap/fe/core/PageController";
3
3
  import type TableAPI from "sap/fe/macros/table/TableAPI";
4
4
  import MessageBox from "sap/m/MessageBox";
5
5
  import Library from "sap/ui/core/Lib";
6
+ import Messaging from "sap/ui/core/Messaging";
7
+ import type Message from "sap/ui/core/message/Message";
6
8
  import type { PasteHelperParseResult } from "sap/ui/core/util/PasteHelper";
7
9
  import * as CorePasteHelper from "sap/ui/core/util/PasteHelper";
8
10
  import type Table from "sap/ui/mdc/Table";
9
11
  import type { PropertyInfo } from "sap/ui/mdc/Table";
10
12
  import type TableDelegate from "sap/ui/mdc/TableDelegate";
13
+ import type Column from "sap/ui/mdc/table/Column";
11
14
  import type Context from "sap/ui/model/Context";
12
15
  import type ODataV4Context from "sap/ui/model/odata/v4/Context";
13
16
 
@@ -16,6 +19,13 @@ export type customValidationMessage = {
16
19
  messageTarget?: string;
17
20
  };
18
21
 
22
+ type PasteInformation = {
23
+ rows: ODataV4Context[];
24
+ columns: Column[];
25
+ updatedRowCount: number;
26
+ numberOfNewCreationRows: number;
27
+ };
28
+
19
29
  const getInfoForEntityProperty = function (propertyPath: any, rowBindingPath: any, metaContext: any, metaModel: any): any {
20
30
  const property = metaContext.getProperty(propertyPath),
21
31
  formatOptions = { parseKeepsEmptyString: true },
@@ -72,7 +82,14 @@ const PasteHelper = {
72
82
  }
73
83
  return errorMessage;
74
84
  },
75
- getColumnInfo: async function (table: Table): Promise<PasteColumnInfo[]> {
85
+ /**
86
+ * Get details about table columns.
87
+ *
88
+ * @param table The table which contains the columns to be analyzed
89
+ * @param columns A list of columns to be analyzed. If undefined, all columns from the table are analyzed
90
+ * @returns An array of objects providing details about columns.
91
+ */
92
+ getColumnInfo: async function (table: Table, columns?: Column[]): Promise<PasteColumnInfo[]> {
76
93
  const model = table.getRowBinding().getModel(),
77
94
  metaModel = model.getMetaModel(),
78
95
  rowBindingPath = model.resolve(table.getRowBinding().getPath(), table.getRowBinding().getContext()),
@@ -83,7 +100,7 @@ const PasteHelper = {
83
100
  ...propertyInfo.map((property: PropertyInfo) => ({ [property.name]: property }))
84
101
  );
85
102
  const columnInfos: PasteColumnInfo[] = [];
86
- table.getColumns().forEach((column) => {
103
+ (columns ?? table.getColumns()).forEach((column) => {
87
104
  const infoProperty = propertyInfoDict[column.getPropertyKey()];
88
105
  // Check if it's a complex property (property associated to multiple simple properties)
89
106
  if (infoProperty.propertyInfos) {
@@ -128,8 +145,16 @@ const PasteHelper = {
128
145
  },
129
146
  getInfoForEntityProperty: getInfoForEntityProperty,
130
147
 
131
- parsePastedData: async function (rawData: unknown[][], table: Table): Promise<Record<string, unknown>[]> {
132
- return this.getColumnInfo(table)
148
+ /**
149
+ * Transform an array of data by parsing it into an array of objects, facilitating the mapping of columns and data.
150
+ *
151
+ * @param rawData The table which contains the columns to be analyzed
152
+ * @param table The table which receives the data
153
+ * @param columns A list of columns to be used to map the data. If undefined, all table columns are used
154
+ * @returns A collection of objects that associates data with corresponding columns.
155
+ */
156
+ parsePastedData: async function (rawData: unknown[][], table: Table, columns?: Column[]): Promise<Record<string, unknown>[]> {
157
+ return this.getColumnInfo(table, columns)
133
158
  .then(function (pasteInfos: any[]) {
134
159
  // Check if we have data for at least the first editable column
135
160
  const pastedColumnCount = rawData.length ? rawData[0].length : 0;
@@ -155,6 +180,216 @@ const PasteHelper = {
155
180
  }
156
181
  });
157
182
  },
183
+
184
+ /**
185
+ * Update an array of contexts.
186
+ *
187
+ * @param contexts Array of contexts to be updated
188
+ * @param data Array of object containing the data to be used to update the contexts
189
+ * @returns Promise
190
+ */
191
+ _updateContexts: async function (contexts: (ODataV4Context | undefined)[], data: Record<string, unknown>[]): Promise<void> {
192
+ let index = 0;
193
+ const setPropertyPromises = [];
194
+ for (const row of data) {
195
+ const rowContext = contexts[index++];
196
+ if (rowContext) {
197
+ for (const key in row) {
198
+ setPropertyPromises.push(rowContext.setProperty(key, row[key]));
199
+ }
200
+ }
201
+ }
202
+ await Promise.allSettled(setPropertyPromises);
203
+ },
204
+
205
+ /**
206
+ * Get information about the paste operation on ResponsiveTable.
207
+ * @param rawData
208
+ * @param cellSelection
209
+ * @param cellSelection.columns
210
+ * @param cellSelection.rows
211
+ * @param posFirstSelectedRow
212
+ * @param table
213
+ * @returns Objet containing Information about the pasting operation
214
+ */
215
+ getPasteInformationForReponsiveTable: function (
216
+ rawData: string[][],
217
+ cellSelection: { columns: Column[]; rows: ODataV4Context[] },
218
+ posFirstSelectedRow: number,
219
+ table: Table
220
+ ): PasteInformation {
221
+ let numberOfNewCreationRows = 0;
222
+ const posFirstInlineCreationRowInTable = table
223
+ .getRowBinding()
224
+ .getCurrentContexts()
225
+ .findIndex((context) => context.isTransient());
226
+ const rows = cellSelection.rows;
227
+ let updatedRowCount = 0;
228
+ const columns =
229
+ cellSelection.columns.length > 1
230
+ ? cellSelection.columns
231
+ : table.getColumns().slice(table.getColumns().indexOf(cellSelection.columns[0]));
232
+
233
+ // only one cell is selected
234
+ if (cellSelection.columns.length === 1 && cellSelection.rows.length === 1) {
235
+ // check if the inline creation row is in the targeted range
236
+ if (
237
+ posFirstSelectedRow <= posFirstInlineCreationRowInTable &&
238
+ posFirstSelectedRow + rawData.length > posFirstInlineCreationRowInTable
239
+ ) {
240
+ numberOfNewCreationRows = rawData.length - (posFirstInlineCreationRowInTable - posFirstSelectedRow) - 1;
241
+ updatedRowCount = rawData.length;
242
+ } else {
243
+ // the inline creation row is not in the targeted range
244
+ numberOfNewCreationRows = 0;
245
+ updatedRowCount = rawData.length;
246
+ }
247
+ } else {
248
+ // multiple cells are selected
249
+ const lastInlineCreationRowInSelection = rows.filter((context) => context.isTransient())?.pop();
250
+ const posLastInlineCreationRowInSelection = lastInlineCreationRowInSelection
251
+ ? rows.indexOf(lastInlineCreationRowInSelection)
252
+ : -1;
253
+ updatedRowCount = Math.min(rawData.length, cellSelection.rows.length);
254
+ // check if the inline creation row is in the selected range
255
+ if (posLastInlineCreationRowInSelection > -1) {
256
+ updatedRowCount = posLastInlineCreationRowInSelection === cellSelection.rows.length - 1 ? rawData.length : updatedRowCount;
257
+ numberOfNewCreationRows =
258
+ posLastInlineCreationRowInSelection === cellSelection.rows.length - 1
259
+ ? rawData.length - posLastInlineCreationRowInSelection - 1
260
+ : 0;
261
+ }
262
+ }
263
+ return { rows, columns, updatedRowCount, numberOfNewCreationRows };
264
+ },
265
+
266
+ /**
267
+ * Get information about the paste operation on GridTable.
268
+ * @param rawData
269
+ * @param cellSelection
270
+ * @param cellSelection.columns
271
+ * @param cellSelection.rows
272
+ * @param posFirstSelectedRow
273
+ * @param table
274
+ * @returns Objet containing Information about the pasting operation
275
+ */
276
+ getPasteInformationForGridTable: function (
277
+ rawData: string[][],
278
+ cellSelection: { columns: Column[]; rows: ODataV4Context[] },
279
+ posFirstSelectedRow: number,
280
+ table: Table
281
+ ): PasteInformation {
282
+ let numberOfNewCreationRows = 0;
283
+ const rows = cellSelection.rows;
284
+ let updatedRowCount = 0;
285
+ const tableRowcCount = table.getRowBinding().getLength();
286
+ let columns =
287
+ cellSelection.columns.length > 1
288
+ ? cellSelection.columns
289
+ : table.getColumns().slice(table.getColumns().indexOf(cellSelection.columns[0]));
290
+ if (cellSelection.columns.length === 1 && cellSelection.rows.length === 1) {
291
+ numberOfNewCreationRows =
292
+ posFirstSelectedRow + rawData.length > tableRowcCount ? posFirstSelectedRow + rawData.length - tableRowcCount : 0;
293
+ columns = table.getColumns().slice(table.getColumns().indexOf(cellSelection.columns[0]));
294
+ updatedRowCount = rawData.length;
295
+ } else {
296
+ // multiple cells are selected
297
+ numberOfNewCreationRows =
298
+ posFirstSelectedRow + rows.length >= tableRowcCount ? posFirstSelectedRow + rawData.length - tableRowcCount : 0;
299
+ updatedRowCount = numberOfNewCreationRows === 0 ? Math.min(rawData.length, cellSelection.rows.length) : rawData.length;
300
+ }
301
+ return { rows, columns, updatedRowCount, numberOfNewCreationRows };
302
+ },
303
+
304
+ /**
305
+ * Get information about the paste operation.
306
+ * @param rawData
307
+ * @param cellSelection
308
+ * @param cellSelection.columns
309
+ * @param cellSelection.rows
310
+ * @param posFirstSelectedRow
311
+ * @param table
312
+ * @returns Objet containing Information about the pasting operation
313
+ */
314
+ getPasteInformation: function (
315
+ rawData: string[][],
316
+ cellSelection: { columns: Column[]; rows: ODataV4Context[] },
317
+ posFirstSelectedRow: number,
318
+ table: Table
319
+ ): PasteInformation | null {
320
+ let pasteInformation: PasteInformation | null = null;
321
+
322
+ switch (table.data("tableType")) {
323
+ case "GridTable":
324
+ pasteInformation = this.getPasteInformationForGridTable(rawData, cellSelection, posFirstSelectedRow, table);
325
+ break;
326
+ case "ResponsiveTable":
327
+ pasteInformation = this.getPasteInformationForReponsiveTable(rawData, cellSelection, posFirstSelectedRow, table);
328
+ break;
329
+ default:
330
+ Log.warning(`Paste operation is not supported for table type ${table.data("tableType")}`);
331
+ }
332
+
333
+ return pasteInformation;
334
+ },
335
+
336
+ /**
337
+ * Paste data into a table using a selection of column and rows.
338
+ *
339
+ * @param rawData The data to be pasted into the table
340
+ * @param cellSelection The columns and the rows to be updated
341
+ * @param cellSelection.columns The columns to be updated
342
+ * @param cellSelection.rows The rows to be updated
343
+ * @param table The table
344
+ * @returns Object containing information about the paste
345
+ */
346
+ pasteRangeData: async function (
347
+ rawData: string[][],
348
+ cellSelection: { columns: Column[]; rows: ODataV4Context[] },
349
+ table: Table
350
+ ): Promise<
351
+ | {
352
+ updatedRowCount: number;
353
+ updatedColCount: number;
354
+ numberOfNewCreationRows: number;
355
+ posFirstInlineCreationRow: number | undefined;
356
+ }
357
+ | undefined
358
+ > {
359
+ const posFirstSelectedRow = cellSelection.rows[0].getIndex()!;
360
+
361
+ const pasteInfo = this.getPasteInformation(rawData, cellSelection, posFirstSelectedRow, table);
362
+ if (!pasteInfo) return;
363
+
364
+ const parsedData = await this.parsePastedData(rawData, table, pasteInfo.columns);
365
+ if (parsedData.length > 0) {
366
+ if (pasteInfo.numberOfNewCreationRows > 0) {
367
+ await (table.getParent() as TableAPI).createEmptyRows(
368
+ table.getRowBinding(),
369
+ table,
370
+ false,
371
+ pasteInfo.numberOfNewCreationRows,
372
+ true
373
+ );
374
+ }
375
+
376
+ //load missing rows if needed including the newly created rows
377
+ pasteInfo.rows = await table.getRowBinding().requestContexts(posFirstSelectedRow, pasteInfo.updatedRowCount);
378
+ await this._updateContexts(pasteInfo.rows, parsedData);
379
+
380
+ // focusing on the first available creation row
381
+ const posFirstInlineCreationRow = pasteInfo.rows.find((context) => context.isTransient())?.getIndex();
382
+ if (posFirstInlineCreationRow) {
383
+ table.focusRow(posFirstInlineCreationRow);
384
+ }
385
+ return {
386
+ updatedRowCount: pasteInfo.updatedRowCount,
387
+ updatedColCount: Object.keys(parsedData[0]).length,
388
+ numberOfNewCreationRows: pasteInfo.numberOfNewCreationRows < 0 ? 0 : pasteInfo.numberOfNewCreationRows,
389
+ posFirstInlineCreationRow
390
+ };
391
+ }
392
+ },
158
393
  pasteData: async function (rawData: string[][], table: Table, controller: PageController): Promise<Context[] | undefined> {
159
394
  const editFlow = controller.editFlow;
160
395
  const tableDefinition = (table.getParent() as TableAPI).getTableDefinition();
@@ -190,15 +425,32 @@ const PasteHelper = {
190
425
  return aData;
191
426
  })
192
427
  .then(async (aValidatedData): Promise<Context[] | undefined> => {
193
- return aValidatedData.length > 0
194
- ? editFlow.createMultipleDocuments(
195
- table.getRowBinding(),
196
- aValidatedData,
197
- tableDefinition?.control?.createAtEnd,
198
- true,
199
- (controller as any).editFlow.onBeforeCreate
200
- )
201
- : undefined;
428
+ // remove the last transient context if it exists
429
+ const transientContexts = table
430
+ .getRowBinding()
431
+ .getCurrentContexts()
432
+ .filter((context) => context.isTransient());
433
+ const lastTransientContext = transientContexts.pop();
434
+ //check if the last transient context has an error message
435
+ const lastTransientContextHasErrorMessage = !!Messaging.getMessageModel()
436
+ .getData()
437
+ .find((message: Message) => lastTransientContext && message.getTargets()[0].includes(lastTransientContext.getPath()));
438
+ const newContexts =
439
+ aValidatedData.length > 0
440
+ ? await editFlow.createMultipleDocuments(
441
+ table.getRowBinding(),
442
+ aValidatedData,
443
+ tableDefinition?.control?.createAtEnd,
444
+ true,
445
+ controller.editFlow.onBeforeCreate
446
+ )
447
+ : undefined;
448
+ // if the last transient context has no error message, delete it and recreate a new one at the last position
449
+ if (lastTransientContext && !lastTransientContextHasErrorMessage) {
450
+ lastTransientContext?.delete();
451
+ await (table.getParent() as TableAPI).createEmptyRows(table.getRowBinding(), table, false, 1);
452
+ }
453
+ return newContexts;
202
454
  })
203
455
  .catch((oError) => {
204
456
  Log.error("Error while pasting data", oError);
@@ -0,0 +1,66 @@
1
+ /*!
2
+ * SAP UI development toolkit for HTML5 (SAPUI5)
3
+ * (c) Copyright 2009-2024 SAP SE. All rights reserved
4
+ */
5
+ sap.ui.define([], function () {
6
+ "use strict";
7
+
8
+ var _exports = {};
9
+ /**
10
+ * Helper class that allows to create a Promise and resolve it "from the outside".
11
+ *
12
+ * For example, to return a string promise that is resolved when an event is fired:
13
+ * <code>
14
+ * const keeper = new PromiseKeeper<string>();
15
+ * eventProvider.attachEvent('myEvent', () => {
16
+ * keeper.resolve("I'm resolved!!");
17
+ * });
18
+ *
19
+ * return keeper.promise;
20
+ * </code>
21
+ */
22
+ let PromiseKeeper = /*#__PURE__*/function () {
23
+ /**
24
+ * The Promise wrapped by the PromiseKeeper
25
+ */
26
+
27
+ function PromiseKeeper() {
28
+ this.promise = new Promise((resolve, reject) => {
29
+ this.resolver = resolve;
30
+ this.rejector = reject;
31
+ });
32
+ }
33
+
34
+ /**
35
+ * Resolves the wrapped Promise.
36
+ *
37
+ * @param result The resolved value.
38
+ */
39
+ _exports = PromiseKeeper;
40
+ var _proto = PromiseKeeper.prototype;
41
+ _proto.resolve = function resolve(result) {
42
+ if (this.resolver) {
43
+ this.resolver(result);
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Rejects the wrapped Promise. The promise is always rejected using an Error object.
49
+ *
50
+ * @param error The error or error message for the rejection.
51
+ */;
52
+ _proto.reject = function reject(error) {
53
+ if (this.rejector) {
54
+ if (error === undefined || typeof error === "string") {
55
+ this.rejector(new Error(error));
56
+ } else {
57
+ this.rejector(error);
58
+ }
59
+ }
60
+ };
61
+ return PromiseKeeper;
62
+ }();
63
+ _exports = PromiseKeeper;
64
+ return _exports;
65
+ }, false);
66
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQcm9taXNlS2VlcGVyIiwicHJvbWlzZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicmVzb2x2ZXIiLCJyZWplY3RvciIsInJlc3VsdCIsImVycm9yIiwidW5kZWZpbmVkIiwiRXJyb3IiXSwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzIjpbIlByb21pc2VLZWVwZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBIZWxwZXIgY2xhc3MgdGhhdCBhbGxvd3MgdG8gY3JlYXRlIGEgUHJvbWlzZSBhbmQgcmVzb2x2ZSBpdCBcImZyb20gdGhlIG91dHNpZGVcIi5cbiAqXG4gKiBGb3IgZXhhbXBsZSwgdG8gcmV0dXJuIGEgc3RyaW5nIHByb21pc2UgdGhhdCBpcyByZXNvbHZlZCB3aGVuIGFuIGV2ZW50IGlzIGZpcmVkOlxuICogPGNvZGU+XG4gKiBcdFx0Y29uc3Qga2VlcGVyID0gbmV3IFByb21pc2VLZWVwZXI8c3RyaW5nPigpO1xuICogXHRcdGV2ZW50UHJvdmlkZXIuYXR0YWNoRXZlbnQoJ215RXZlbnQnLCAoKSA9PiB7XG4gKiBcdFx0XHRrZWVwZXIucmVzb2x2ZShcIkknbSByZXNvbHZlZCEhXCIpO1xuICogXHRcdH0pO1xuICpcbiAqIFx0XHRyZXR1cm4ga2VlcGVyLnByb21pc2U7XG4gKiA8L2NvZGU+XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFByb21pc2VLZWVwZXI8VHlwZT4ge1xuXHRwcml2YXRlIHJlc29sdmVyPzogKHJlc3VsdDogVHlwZSkgPT4gdm9pZDtcblxuXHRwcml2YXRlIHJlamVjdG9yPzogKGVycm9yOiBFcnJvcikgPT4gdm9pZDtcblxuXHQvKipcblx0ICogVGhlIFByb21pc2Ugd3JhcHBlZCBieSB0aGUgUHJvbWlzZUtlZXBlclxuXHQgKi9cblx0cHVibGljIHJlYWRvbmx5IHByb21pc2U6IFByb21pc2U8VHlwZT47XG5cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0dGhpcy5wcm9taXNlID0gbmV3IFByb21pc2U8VHlwZT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdFx0dGhpcy5yZXNvbHZlciA9IHJlc29sdmU7XG5cdFx0XHR0aGlzLnJlamVjdG9yID0gcmVqZWN0O1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlc29sdmVzIHRoZSB3cmFwcGVkIFByb21pc2UuXG5cdCAqXG5cdCAqIEBwYXJhbSByZXN1bHQgVGhlIHJlc29sdmVkIHZhbHVlLlxuXHQgKi9cblx0cmVzb2x2ZShyZXN1bHQ6IFR5cGUpOiB2b2lkIHtcblx0XHRpZiAodGhpcy5yZXNvbHZlcikge1xuXHRcdFx0dGhpcy5yZXNvbHZlcihyZXN1bHQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZWplY3RzIHRoZSB3cmFwcGVkIFByb21pc2UuIFRoZSBwcm9taXNlIGlzIGFsd2F5cyByZWplY3RlZCB1c2luZyBhbiBFcnJvciBvYmplY3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBlcnJvciBUaGUgZXJyb3Igb3IgZXJyb3IgbWVzc2FnZSBmb3IgdGhlIHJlamVjdGlvbi5cblx0ICovXG5cdHJlamVjdChlcnJvcj86IHN0cmluZyB8IEVycm9yKTogdm9pZCB7XG5cdFx0aWYgKHRoaXMucmVqZWN0b3IpIHtcblx0XHRcdGlmIChlcnJvciA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiBlcnJvciA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0XHR0aGlzLnJlamVjdG9yKG5ldyBFcnJvcihlcnJvcikpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5yZWplY3RvcihlcnJvcik7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUFBO0FBQUE7Ozs7O0VBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFaQSxJQWFxQkEsYUFBYTtJQUtqQztBQUNEO0FBQ0E7O0lBR0MseUJBQWM7TUFDYixJQUFJLENBQUNDLE9BQU8sR0FBRyxJQUFJQyxPQUFPLENBQU8sQ0FBQ0MsT0FBTyxFQUFFQyxNQUFNLEtBQUs7UUFDckQsSUFBSSxDQUFDQyxRQUFRLEdBQUdGLE9BQU87UUFDdkIsSUFBSSxDQUFDRyxRQUFRLEdBQUdGLE1BQU07TUFDdkIsQ0FBQyxDQUFDO0lBQ0g7O0lBRUE7QUFDRDtBQUNBO0FBQ0E7QUFDQTtJQUpDO0lBQUE7SUFBQSxPQUtBRCxPQUFPLEdBQVAsaUJBQVFJLE1BQVksRUFBUTtNQUMzQixJQUFJLElBQUksQ0FBQ0YsUUFBUSxFQUFFO1FBQ2xCLElBQUksQ0FBQ0EsUUFBUSxDQUFDRSxNQUFNLENBQUM7TUFDdEI7SUFDRDs7SUFFQTtBQUNEO0FBQ0E7QUFDQTtBQUNBLE9BSkM7SUFBQSxPQUtBSCxNQUFNLEdBQU4sZ0JBQU9JLEtBQXNCLEVBQVE7TUFDcEMsSUFBSSxJQUFJLENBQUNGLFFBQVEsRUFBRTtRQUNsQixJQUFJRSxLQUFLLEtBQUtDLFNBQVMsSUFBSSxPQUFPRCxLQUFLLEtBQUssUUFBUSxFQUFFO1VBQ3JELElBQUksQ0FBQ0YsUUFBUSxDQUFDLElBQUlJLEtBQUssQ0FBQ0YsS0FBSyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxNQUFNO1VBQ04sSUFBSSxDQUFDRixRQUFRLENBQUNFLEtBQUssQ0FBQztRQUNyQjtNQUNEO0lBQ0QsQ0FBQztJQUFBO0VBQUE7RUFBQTtFQUFBO0FBQUEifQ==
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Helper class that allows to create a Promise and resolve it "from the outside".
3
+ *
4
+ * For example, to return a string promise that is resolved when an event is fired:
5
+ * <code>
6
+ * const keeper = new PromiseKeeper<string>();
7
+ * eventProvider.attachEvent('myEvent', () => {
8
+ * keeper.resolve("I'm resolved!!");
9
+ * });
10
+ *
11
+ * return keeper.promise;
12
+ * </code>
13
+ */
14
+ export default class PromiseKeeper<Type> {
15
+ private resolver?: (result: Type) => void;
16
+
17
+ private rejector?: (error: Error) => void;
18
+
19
+ /**
20
+ * The Promise wrapped by the PromiseKeeper
21
+ */
22
+ public readonly promise: Promise<Type>;
23
+
24
+ constructor() {
25
+ this.promise = new Promise<Type>((resolve, reject) => {
26
+ this.resolver = resolve;
27
+ this.rejector = reject;
28
+ });
29
+ }
30
+
31
+ /**
32
+ * Resolves the wrapped Promise.
33
+ *
34
+ * @param result The resolved value.
35
+ */
36
+ resolve(result: Type): void {
37
+ if (this.resolver) {
38
+ this.resolver(result);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Rejects the wrapped Promise. The promise is always rejected using an Error object.
44
+ *
45
+ * @param error The error or error message for the rejection.
46
+ */
47
+ reject(error?: string | Error): void {
48
+ if (this.rejector) {
49
+ if (error === undefined || typeof error === "string") {
50
+ this.rejector(new Error(error));
51
+ } else {
52
+ this.rejector(error);
53
+ }
54
+ }
55
+ }
56
+ }
@@ -17,6 +17,21 @@ sap.ui.define(["sap/base/Log"], function (Log) {
17
17
  semanticKeys: aSemanticKeys
18
18
  };
19
19
  },
20
+ /**
21
+ * Returns a stringified version of a list of key values, e.g. [{name:"aa", value:1}, {name:"bb", value:"foo"}] --> "aa=1,bb='foo'".
22
+ *
23
+ * @param valuePairs
24
+ * @param typeMetadata
25
+ * @returns String
26
+ */
27
+ getPathContent(valuePairs, typeMetadata) {
28
+ const singleKey = valuePairs.length === 1;
29
+ return valuePairs.map(valuePair => {
30
+ const keyValue = valuePair.value;
31
+ const encodedKeyValue = typeMetadata[valuePair.name].$Type === "Edm.String" ? `'${encodeURIComponent(keyValue)}'` : keyValue;
32
+ return singleKey ? encodedKeyValue : `${valuePair.name}=${encodedKeyValue}`;
33
+ }).join(",");
34
+ },
20
35
  getSemanticPath: function (oContext) {
21
36
  let bStrict = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
22
37
  const oMetaModel = oContext.getModel().getMetaModel(),
@@ -28,28 +43,24 @@ sap.ui.define(["sap/base/Log"], function (Log) {
28
43
  } else {
29
44
  sTechnicalPath = oContext.getPath();
30
45
  }
31
- if (this._isPathForSemantic(sTechnicalPath) && oSemanticObjectInformation.semanticKeys) {
46
+ if (this._isPathForSemantic(sTechnicalPath) && oSemanticObjectInformation.semanticKeys && oSemanticObjectInformation.semanticKeys.length !== 0) {
32
47
  const aSemanticKeys = oSemanticObjectInformation.semanticKeys;
33
48
  const oEntityType = oMetaModel.getObject("/" + oMetaModel.getObject(`/${sEntitySetName}`).$Type);
34
49
  try {
35
- const sSemanticKeysPart = aSemanticKeys.map(function (oSemanticKey) {
36
- const sPropertyPath = oSemanticKey.$PropertyPath;
37
- let sKeyValue = oContext.getProperty(sPropertyPath);
38
- if (sKeyValue === undefined || sKeyValue === null) {
39
- throw new Error(`Couldn't resolve semantic key value for ${sPropertyPath}`);
40
- } else {
41
- if (oEntityType[sPropertyPath].$Type === "Edm.String") {
42
- sKeyValue = `'${encodeURIComponent(sKeyValue)}'`;
43
- }
44
- if (aSemanticKeys.length > 1) {
45
- // Several semantic keys --> path should be entitySet(key1=value1, key2=value2, ...)
46
- // Otherwise we keep entitySet(keyValue)
47
- sKeyValue = `${sPropertyPath}=${sKeyValue}`;
48
- }
49
- return sKeyValue;
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ const keyValues = aSemanticKeys.map(semanticKey => {
52
+ const keyName = semanticKey.$PropertyPath;
53
+ const keyValue = oContext.getProperty(keyName);
54
+ if (keyValue === undefined || keyValue === null) {
55
+ throw new Error(`Couldn't resolve semantic key value for ${keyName}`);
50
56
  }
51
- }).join(",");
52
- sSemanticPath = `/${sEntitySetName}(${sSemanticKeysPart})`;
57
+ return {
58
+ name: keyName,
59
+ value: keyValue
60
+ };
61
+ });
62
+ const semanticKeysPart = this.getPathContent(keyValues, oEntityType);
63
+ sSemanticPath = `/${sEntitySetName}(${semanticKeysPart})`;
53
64
  } catch (e) {
54
65
  Log.info(e);
55
66
  }
@@ -67,4 +78,4 @@ sap.ui.define(["sap/base/Log"], function (Log) {
67
78
  };
68
79
  return SemanticKeyHelper;
69
80
  }, false);
70
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJTZW1hbnRpY0tleUhlbHBlciIsImdldFNlbWFudGljS2V5cyIsIm9NZXRhTW9kZWwiLCJzRW50aXR5U2V0TmFtZSIsImdldE9iamVjdCIsImdldFNlbWFudGljT2JqZWN0SW5mb3JtYXRpb24iLCJvU2VtYW50aWNPYmplY3QiLCJhU2VtYW50aWNLZXlzIiwic2VtYW50aWNPYmplY3QiLCJzZW1hbnRpY0tleXMiLCJnZXRTZW1hbnRpY1BhdGgiLCJvQ29udGV4dCIsImJTdHJpY3QiLCJnZXRNb2RlbCIsImdldE1ldGFNb2RlbCIsImdldE1ldGFDb250ZXh0IiwiZ2V0UGF0aCIsIm9TZW1hbnRpY09iamVjdEluZm9ybWF0aW9uIiwic1RlY2huaWNhbFBhdGgiLCJzU2VtYW50aWNQYXRoIiwiaXNBIiwiaXNSZWxhdGl2ZSIsImdldEhlYWRlckNvbnRleHQiLCJfaXNQYXRoRm9yU2VtYW50aWMiLCJvRW50aXR5VHlwZSIsIiRUeXBlIiwic1NlbWFudGljS2V5c1BhcnQiLCJtYXAiLCJvU2VtYW50aWNLZXkiLCJzUHJvcGVydHlQYXRoIiwiJFByb3BlcnR5UGF0aCIsInNLZXlWYWx1ZSIsImdldFByb3BlcnR5IiwidW5kZWZpbmVkIiwiRXJyb3IiLCJlbmNvZGVVUklDb21wb25lbnQiLCJsZW5ndGgiLCJqb2luIiwiZSIsIkxvZyIsImluZm8iLCJzUGF0aCIsInRlc3QiXSwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzIjpbIlNlbWFudGljS2V5SGVscGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUHJvcGVydHlQYXRoIH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzXCI7XG5pbXBvcnQgdHlwZSB7IFNlbWFudGljT2JqZWN0IH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzL3ZvY2FidWxhcmllcy9Db21tb25cIjtcbmltcG9ydCBMb2cgZnJvbSBcInNhcC9iYXNlL0xvZ1wiO1xuaW1wb3J0IHR5cGUgT0RhdGFWNENvbnRleHQgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9Db250ZXh0XCI7XG5pbXBvcnQgdHlwZSBPRGF0YUxpc3RCaW5kaW5nIGZyb20gXCJzYXAvdWkvbW9kZWwvb2RhdGEvdjQvT0RhdGFMaXN0QmluZGluZ1wiO1xuaW1wb3J0IHR5cGUgT0RhdGFNZXRhTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9PRGF0YU1ldGFNb2RlbFwiO1xuaW1wb3J0IHR5cGUgeyBFeHBhbmRQYXRoVHlwZSwgTWV0YU1vZGVsVHlwZSB9IGZyb20gXCJ0eXBlcy9tZXRhbW9kZWxfdHlwZXNcIjtcblxudHlwZSBTZW1hbnRpY09iamVjdEluZm9ybWF0aW9uID0ge1xuXHRzZW1hbnRpY09iamVjdD86IE1ldGFNb2RlbFR5cGU8U2VtYW50aWNPYmplY3Q+O1xuXHRzZW1hbnRpY0tleXM/OiBFeHBhbmRQYXRoVHlwZTxQcm9wZXJ0eVBhdGg+W107XG59O1xuY29uc3QgU2VtYW50aWNLZXlIZWxwZXIgPSB7XG5cdGdldFNlbWFudGljS2V5czogZnVuY3Rpb24gKG9NZXRhTW9kZWw6IE9EYXRhTWV0YU1vZGVsLCBzRW50aXR5U2V0TmFtZTogc3RyaW5nKTogRXhwYW5kUGF0aFR5cGU8UHJvcGVydHlQYXRoPltdIHwgdW5kZWZpbmVkIHtcblx0XHRyZXR1cm4gb01ldGFNb2RlbC5nZXRPYmplY3QoYC8ke3NFbnRpdHlTZXROYW1lfS9AY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLlNlbWFudGljS2V5YCk7XG5cdH0sXG5cdGdldFNlbWFudGljT2JqZWN0SW5mb3JtYXRpb246IGZ1bmN0aW9uIChvTWV0YU1vZGVsOiBPRGF0YU1ldGFNb2RlbCwgc0VudGl0eVNldE5hbWU6IHN0cmluZyk6IFNlbWFudGljT2JqZWN0SW5mb3JtYXRpb24ge1xuXHRcdGNvbnN0IG9TZW1hbnRpY09iamVjdCA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KGAvJHtzRW50aXR5U2V0TmFtZX0vQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5TZW1hbnRpY09iamVjdGApIGFzXG5cdFx0XHR8IE1ldGFNb2RlbFR5cGU8U2VtYW50aWNPYmplY3Q+XG5cdFx0XHR8IHVuZGVmaW5lZDtcblx0XHRjb25zdCBhU2VtYW50aWNLZXlzID0gdGhpcy5nZXRTZW1hbnRpY0tleXMob01ldGFNb2RlbCwgc0VudGl0eVNldE5hbWUpO1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW1hbnRpY09iamVjdDogb1NlbWFudGljT2JqZWN0LFxuXHRcdFx0c2VtYW50aWNLZXlzOiBhU2VtYW50aWNLZXlzXG5cdFx0fTtcblx0fSxcblx0Z2V0U2VtYW50aWNQYXRoOiBmdW5jdGlvbiAob0NvbnRleHQ6IE9EYXRhVjRDb250ZXh0LCBiU3RyaWN0ID0gZmFsc2UpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuXHRcdGNvbnN0IG9NZXRhTW9kZWwgPSBvQ29udGV4dC5nZXRNb2RlbCgpLmdldE1ldGFNb2RlbCgpLFxuXHRcdFx0c0VudGl0eVNldE5hbWUgPSBvTWV0YU1vZGVsLmdldE1ldGFDb250ZXh0KG9Db250ZXh0LmdldFBhdGgoKSkuZ2V0T2JqZWN0KFwiQHNhcHVpLm5hbWVcIiksXG5cdFx0XHRvU2VtYW50aWNPYmplY3RJbmZvcm1hdGlvbiA9IHRoaXMuZ2V0U2VtYW50aWNPYmplY3RJbmZvcm1hdGlvbihvTWV0YU1vZGVsLCBzRW50aXR5U2V0TmFtZSk7XG5cdFx0bGV0IHNUZWNobmljYWxQYXRoLCBzU2VtYW50aWNQYXRoO1xuXG5cdFx0aWYgKG9Db250ZXh0LmlzQTxPRGF0YUxpc3RCaW5kaW5nPihcInNhcC51aS5tb2RlbC5vZGF0YS52NC5PRGF0YUxpc3RCaW5kaW5nXCIpICYmIG9Db250ZXh0LmlzUmVsYXRpdmUoKSkge1xuXHRcdFx0c1RlY2huaWNhbFBhdGggPSBvQ29udGV4dC5nZXRIZWFkZXJDb250ZXh0KCkhLmdldFBhdGgoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0c1RlY2huaWNhbFBhdGggPSBvQ29udGV4dC5nZXRQYXRoKCk7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX2lzUGF0aEZvclNlbWFudGljKHNUZWNobmljYWxQYXRoKSAmJiBvU2VtYW50aWNPYmplY3RJbmZvcm1hdGlvbi5zZW1hbnRpY0tleXMpIHtcblx0XHRcdGNvbnN0IGFTZW1hbnRpY0tleXMgPSBvU2VtYW50aWNPYmplY3RJbmZvcm1hdGlvbi5zZW1hbnRpY0tleXM7XG5cdFx0XHRjb25zdCBvRW50aXR5VHlwZSA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KFwiL1wiICsgb01ldGFNb2RlbC5nZXRPYmplY3QoYC8ke3NFbnRpdHlTZXROYW1lfWApLiRUeXBlKTtcblxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Y29uc3Qgc1NlbWFudGljS2V5c1BhcnQgPSBhU2VtYW50aWNLZXlzXG5cdFx0XHRcdFx0Lm1hcChmdW5jdGlvbiAob1NlbWFudGljS2V5KSB7XG5cdFx0XHRcdFx0XHRjb25zdCBzUHJvcGVydHlQYXRoID0gb1NlbWFudGljS2V5LiRQcm9wZXJ0eVBhdGg7XG5cdFx0XHRcdFx0XHRsZXQgc0tleVZhbHVlID0gb0NvbnRleHQuZ2V0UHJvcGVydHkoc1Byb3BlcnR5UGF0aCk7XG5cblx0XHRcdFx0XHRcdGlmIChzS2V5VmFsdWUgPT09IHVuZGVmaW5lZCB8fCBzS2V5VmFsdWUgPT09IG51bGwpIHtcblx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBDb3VsZG4ndCByZXNvbHZlIHNlbWFudGljIGtleSB2YWx1ZSBmb3IgJHtzUHJvcGVydHlQYXRofWApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0aWYgKG9FbnRpdHlUeXBlW3NQcm9wZXJ0eVBhdGhdLiRUeXBlID09PSBcIkVkbS5TdHJpbmdcIikge1xuXHRcdFx0XHRcdFx0XHRcdHNLZXlWYWx1ZSA9IGAnJHtlbmNvZGVVUklDb21wb25lbnQoc0tleVZhbHVlKX0nYDtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRpZiAoYVNlbWFudGljS2V5cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gU2V2ZXJhbCBzZW1hbnRpYyBrZXlzIC0tPiBwYXRoIHNob3VsZCBiZSBlbnRpdHlTZXQoa2V5MT12YWx1ZTEsIGtleTI9dmFsdWUyLCAuLi4pXG5cdFx0XHRcdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlIHdlIGtlZXAgZW50aXR5U2V0KGtleVZhbHVlKVxuXHRcdFx0XHRcdFx0XHRcdHNLZXlWYWx1ZSA9IGAke3NQcm9wZXJ0eVBhdGh9PSR7c0tleVZhbHVlfWA7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0cmV0dXJuIHNLZXlWYWx1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5qb2luKFwiLFwiKTtcblxuXHRcdFx0XHRzU2VtYW50aWNQYXRoID0gYC8ke3NFbnRpdHlTZXROYW1lfSgke3NTZW1hbnRpY0tleXNQYXJ0fSlgO1xuXHRcdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0XHRMb2cuaW5mbyhlIGFzIHN0cmluZyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGJTdHJpY3QgPyBzU2VtYW50aWNQYXRoIDogc1NlbWFudGljUGF0aCB8fCBzVGVjaG5pY2FsUGF0aDtcblx0fSxcblxuXHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblx0Ly8gSU5URVJOQUwgTUVUSE9EU1xuXHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuXHRfaXNQYXRoRm9yU2VtYW50aWM6IGZ1bmN0aW9uIChzUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG5cdFx0Ly8gT25seSBwYXRoIG9uIHJvb3Qgb2JqZWN0cyBhbGxvdyBzZW1hbnRpYyBrZXlzLCBpLmUuIHNQYXRoID0geHh4KHl5eSlcblx0XHRyZXR1cm4gL15bXigpXStcXChbXigpXStcXCkkLy50ZXN0KHNQYXRoKTtcblx0fVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2VtYW50aWNLZXlIZWxwZXI7XG4iXSwibWFwcGluZ3MiOiI7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
81
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJTZW1hbnRpY0tleUhlbHBlciIsImdldFNlbWFudGljS2V5cyIsIm9NZXRhTW9kZWwiLCJzRW50aXR5U2V0TmFtZSIsImdldE9iamVjdCIsImdldFNlbWFudGljT2JqZWN0SW5mb3JtYXRpb24iLCJvU2VtYW50aWNPYmplY3QiLCJhU2VtYW50aWNLZXlzIiwic2VtYW50aWNPYmplY3QiLCJzZW1hbnRpY0tleXMiLCJnZXRQYXRoQ29udGVudCIsInZhbHVlUGFpcnMiLCJ0eXBlTWV0YWRhdGEiLCJzaW5nbGVLZXkiLCJsZW5ndGgiLCJtYXAiLCJ2YWx1ZVBhaXIiLCJrZXlWYWx1ZSIsInZhbHVlIiwiZW5jb2RlZEtleVZhbHVlIiwibmFtZSIsIiRUeXBlIiwiZW5jb2RlVVJJQ29tcG9uZW50Iiwiam9pbiIsImdldFNlbWFudGljUGF0aCIsIm9Db250ZXh0IiwiYlN0cmljdCIsImdldE1vZGVsIiwiZ2V0TWV0YU1vZGVsIiwiZ2V0TWV0YUNvbnRleHQiLCJnZXRQYXRoIiwib1NlbWFudGljT2JqZWN0SW5mb3JtYXRpb24iLCJzVGVjaG5pY2FsUGF0aCIsInNTZW1hbnRpY1BhdGgiLCJpc0EiLCJpc1JlbGF0aXZlIiwiZ2V0SGVhZGVyQ29udGV4dCIsIl9pc1BhdGhGb3JTZW1hbnRpYyIsIm9FbnRpdHlUeXBlIiwia2V5VmFsdWVzIiwic2VtYW50aWNLZXkiLCJrZXlOYW1lIiwiJFByb3BlcnR5UGF0aCIsImdldFByb3BlcnR5IiwidW5kZWZpbmVkIiwiRXJyb3IiLCJzZW1hbnRpY0tleXNQYXJ0IiwiZSIsIkxvZyIsImluZm8iLCJzUGF0aCIsInRlc3QiXSwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzIjpbIlNlbWFudGljS2V5SGVscGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUHJvcGVydHlQYXRoIH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzXCI7XG5pbXBvcnQgdHlwZSB7IFNlbWFudGljT2JqZWN0IH0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzL3ZvY2FidWxhcmllcy9Db21tb25cIjtcbmltcG9ydCBMb2cgZnJvbSBcInNhcC9iYXNlL0xvZ1wiO1xuaW1wb3J0IHR5cGUgT0RhdGFWNENvbnRleHQgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9Db250ZXh0XCI7XG5pbXBvcnQgdHlwZSBPRGF0YUxpc3RCaW5kaW5nIGZyb20gXCJzYXAvdWkvbW9kZWwvb2RhdGEvdjQvT0RhdGFMaXN0QmluZGluZ1wiO1xuaW1wb3J0IHR5cGUgT0RhdGFNZXRhTW9kZWwgZnJvbSBcInNhcC91aS9tb2RlbC9vZGF0YS92NC9PRGF0YU1ldGFNb2RlbFwiO1xuaW1wb3J0IHR5cGUgeyBFeHBhbmRQYXRoVHlwZSwgTWV0YU1vZGVsVHlwZSB9IGZyb20gXCJ0eXBlcy9tZXRhbW9kZWxfdHlwZXNcIjtcblxudHlwZSBTZW1hbnRpY09iamVjdEluZm9ybWF0aW9uID0ge1xuXHRzZW1hbnRpY09iamVjdD86IE1ldGFNb2RlbFR5cGU8U2VtYW50aWNPYmplY3Q+O1xuXHRzZW1hbnRpY0tleXM/OiBFeHBhbmRQYXRoVHlwZTxQcm9wZXJ0eVBhdGg+W107XG59O1xuY29uc3QgU2VtYW50aWNLZXlIZWxwZXIgPSB7XG5cdGdldFNlbWFudGljS2V5czogZnVuY3Rpb24gKG9NZXRhTW9kZWw6IE9EYXRhTWV0YU1vZGVsLCBzRW50aXR5U2V0TmFtZTogc3RyaW5nKTogRXhwYW5kUGF0aFR5cGU8UHJvcGVydHlQYXRoPltdIHwgdW5kZWZpbmVkIHtcblx0XHRyZXR1cm4gb01ldGFNb2RlbC5nZXRPYmplY3QoYC8ke3NFbnRpdHlTZXROYW1lfS9AY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLlNlbWFudGljS2V5YCk7XG5cdH0sXG5cdGdldFNlbWFudGljT2JqZWN0SW5mb3JtYXRpb246IGZ1bmN0aW9uIChvTWV0YU1vZGVsOiBPRGF0YU1ldGFNb2RlbCwgc0VudGl0eVNldE5hbWU6IHN0cmluZyk6IFNlbWFudGljT2JqZWN0SW5mb3JtYXRpb24ge1xuXHRcdGNvbnN0IG9TZW1hbnRpY09iamVjdCA9IG9NZXRhTW9kZWwuZ2V0T2JqZWN0KGAvJHtzRW50aXR5U2V0TmFtZX0vQGNvbS5zYXAudm9jYWJ1bGFyaWVzLkNvbW1vbi52MS5TZW1hbnRpY09iamVjdGApIGFzXG5cdFx0XHR8IE1ldGFNb2RlbFR5cGU8U2VtYW50aWNPYmplY3Q+XG5cdFx0XHR8IHVuZGVmaW5lZDtcblx0XHRjb25zdCBhU2VtYW50aWNLZXlzID0gdGhpcy5nZXRTZW1hbnRpY0tleXMob01ldGFNb2RlbCwgc0VudGl0eVNldE5hbWUpO1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW1hbnRpY09iamVjdDogb1NlbWFudGljT2JqZWN0LFxuXHRcdFx0c2VtYW50aWNLZXlzOiBhU2VtYW50aWNLZXlzXG5cdFx0fTtcblx0fSxcblx0LyoqXG5cdCAqIFJldHVybnMgYSBzdHJpbmdpZmllZCB2ZXJzaW9uIG9mIGEgbGlzdCBvZiBrZXkgdmFsdWVzLCBlLmcuIFt7bmFtZTpcImFhXCIsIHZhbHVlOjF9LCB7bmFtZTpcImJiXCIsIHZhbHVlOlwiZm9vXCJ9XSAtLT4gXCJhYT0xLGJiPSdmb28nXCIuXG5cdCAqXG5cdCAqIEBwYXJhbSB2YWx1ZVBhaXJzXG5cdCAqIEBwYXJhbSB0eXBlTWV0YWRhdGFcblx0ICogQHJldHVybnMgU3RyaW5nXG5cdCAqL1xuXHRnZXRQYXRoQ29udGVudCh2YWx1ZVBhaXJzOiB7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHVua25vd24gfVtdLCB0eXBlTWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIHsgJFR5cGU6IHN0cmluZyB9Pik6IHN0cmluZyB7XG5cdFx0Y29uc3Qgc2luZ2xlS2V5ID0gdmFsdWVQYWlycy5sZW5ndGggPT09IDE7XG5cdFx0cmV0dXJuIHZhbHVlUGFpcnNcblx0XHRcdC5tYXAoKHZhbHVlUGFpcikgPT4ge1xuXHRcdFx0XHRjb25zdCBrZXlWYWx1ZSA9IHZhbHVlUGFpci52YWx1ZTtcblx0XHRcdFx0Y29uc3QgZW5jb2RlZEtleVZhbHVlID1cblx0XHRcdFx0XHR0eXBlTWV0YWRhdGFbdmFsdWVQYWlyLm5hbWVdLiRUeXBlID09PSBcIkVkbS5TdHJpbmdcIiA/IGAnJHtlbmNvZGVVUklDb21wb25lbnQoa2V5VmFsdWUgYXMgc3RyaW5nKX0nYCA6IGtleVZhbHVlO1xuXHRcdFx0XHRyZXR1cm4gc2luZ2xlS2V5ID8gZW5jb2RlZEtleVZhbHVlIDogYCR7dmFsdWVQYWlyLm5hbWV9PSR7ZW5jb2RlZEtleVZhbHVlfWA7XG5cdFx0XHR9KVxuXHRcdFx0LmpvaW4oXCIsXCIpO1xuXHR9LFxuXHRnZXRTZW1hbnRpY1BhdGg6IGZ1bmN0aW9uIChvQ29udGV4dDogT0RhdGFWNENvbnRleHQsIGJTdHJpY3QgPSBmYWxzZSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG5cdFx0Y29uc3Qgb01ldGFNb2RlbCA9IG9Db250ZXh0LmdldE1vZGVsKCkuZ2V0TWV0YU1vZGVsKCksXG5cdFx0XHRzRW50aXR5U2V0TmFtZSA9IG9NZXRhTW9kZWwuZ2V0TWV0YUNvbnRleHQob0NvbnRleHQuZ2V0UGF0aCgpKS5nZXRPYmplY3QoXCJAc2FwdWkubmFtZVwiKSxcblx0XHRcdG9TZW1hbnRpY09iamVjdEluZm9ybWF0aW9uID0gdGhpcy5nZXRTZW1hbnRpY09iamVjdEluZm9ybWF0aW9uKG9NZXRhTW9kZWwsIHNFbnRpdHlTZXROYW1lKTtcblx0XHRsZXQgc1RlY2huaWNhbFBhdGgsIHNTZW1hbnRpY1BhdGg7XG5cblx0XHRpZiAob0NvbnRleHQuaXNBPE9EYXRhTGlzdEJpbmRpbmc+KFwic2FwLnVpLm1vZGVsLm9kYXRhLnY0Lk9EYXRhTGlzdEJpbmRpbmdcIikgJiYgb0NvbnRleHQuaXNSZWxhdGl2ZSgpKSB7XG5cdFx0XHRzVGVjaG5pY2FsUGF0aCA9IG9Db250ZXh0LmdldEhlYWRlckNvbnRleHQoKSEuZ2V0UGF0aCgpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRzVGVjaG5pY2FsUGF0aCA9IG9Db250ZXh0LmdldFBhdGgoKTtcblx0XHR9XG5cblx0XHRpZiAoXG5cdFx0XHR0aGlzLl9pc1BhdGhGb3JTZW1hbnRpYyhzVGVjaG5pY2FsUGF0aCkgJiZcblx0XHRcdG9TZW1hbnRpY09iamVjdEluZm9ybWF0aW9uLnNlbWFudGljS2V5cyAmJlxuXHRcdFx0b1NlbWFudGljT2JqZWN0SW5mb3JtYXRpb24uc2VtYW50aWNLZXlzLmxlbmd0aCAhPT0gMFxuXHRcdCkge1xuXHRcdFx0Y29uc3QgYVNlbWFudGljS2V5cyA9IG9TZW1hbnRpY09iamVjdEluZm9ybWF0aW9uLnNlbWFudGljS2V5cztcblx0XHRcdGNvbnN0IG9FbnRpdHlUeXBlID0gb01ldGFNb2RlbC5nZXRPYmplY3QoXCIvXCIgKyBvTWV0YU1vZGVsLmdldE9iamVjdChgLyR7c0VudGl0eVNldE5hbWV9YCkuJFR5cGUpO1xuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuXHRcdFx0XHRjb25zdCBrZXlWYWx1ZXMgPSBhU2VtYW50aWNLZXlzLm1hcCgoc2VtYW50aWNLZXkpID0+IHtcblx0XHRcdFx0XHRjb25zdCBrZXlOYW1lID0gc2VtYW50aWNLZXkuJFByb3BlcnR5UGF0aDtcblx0XHRcdFx0XHRjb25zdCBrZXlWYWx1ZSA9IG9Db250ZXh0LmdldFByb3BlcnR5KGtleU5hbWUpO1xuXHRcdFx0XHRcdGlmIChrZXlWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8IGtleVZhbHVlID09PSBudWxsKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoYENvdWxkbid0IHJlc29sdmUgc2VtYW50aWMga2V5IHZhbHVlIGZvciAke2tleU5hbWV9YCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB7IG5hbWU6IGtleU5hbWUsIHZhbHVlOiBrZXlWYWx1ZSB9O1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0Y29uc3Qgc2VtYW50aWNLZXlzUGFydCA9IHRoaXMuZ2V0UGF0aENvbnRlbnQoa2V5VmFsdWVzLCBvRW50aXR5VHlwZSk7XG5cblx0XHRcdFx0c1NlbWFudGljUGF0aCA9IGAvJHtzRW50aXR5U2V0TmFtZX0oJHtzZW1hbnRpY0tleXNQYXJ0fSlgO1xuXHRcdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0XHRMb2cuaW5mbyhlIGFzIHN0cmluZyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGJTdHJpY3QgPyBzU2VtYW50aWNQYXRoIDogc1NlbWFudGljUGF0aCB8fCBzVGVjaG5pY2FsUGF0aDtcblx0fSxcblxuXHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblx0Ly8gSU5URVJOQUwgTUVUSE9EU1xuXHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuXHRfaXNQYXRoRm9yU2VtYW50aWM6IGZ1bmN0aW9uIChzUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG5cdFx0Ly8gT25seSBwYXRoIG9uIHJvb3Qgb2JqZWN0cyBhbGxvdyBzZW1hbnRpYyBrZXlzLCBpLmUuIHNQYXRoID0geHh4KHl5eSlcblx0XHRyZXR1cm4gL15bXigpXStcXChbXigpXStcXCkkLy50ZXN0KHNQYXRoKTtcblx0fVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2VtYW50aWNLZXlIZWxwZXI7XG4iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUFBO0FBQUE7Ozs7RUFZQSxNQUFNQSxpQkFBaUIsR0FBRztJQUN6QkMsZUFBZSxFQUFFLFVBQVVDLFVBQTBCLEVBQUVDLGNBQXNCLEVBQThDO01BQzFILE9BQU9ELFVBQVUsQ0FBQ0UsU0FBUyxDQUFFLElBQUdELGNBQWUsOENBQTZDLENBQUM7SUFDOUYsQ0FBQztJQUNERSw0QkFBNEIsRUFBRSxVQUFVSCxVQUEwQixFQUFFQyxjQUFzQixFQUE2QjtNQUN0SCxNQUFNRyxlQUFlLEdBQUdKLFVBQVUsQ0FBQ0UsU0FBUyxDQUFFLElBQUdELGNBQWUsaURBQWdELENBRXBHO01BQ1osTUFBTUksYUFBYSxHQUFHLElBQUksQ0FBQ04sZUFB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
@@ -24,6 +24,24 @@ const SemanticKeyHelper = {
24
24
  semanticKeys: aSemanticKeys
25
25
  };
26
26
  },
27
+ /**
28
+ * Returns a stringified version of a list of key values, e.g. [{name:"aa", value:1}, {name:"bb", value:"foo"}] --> "aa=1,bb='foo'".
29
+ *
30
+ * @param valuePairs
31
+ * @param typeMetadata
32
+ * @returns String
33
+ */
34
+ getPathContent(valuePairs: { name: string; value: unknown }[], typeMetadata: Record<string, { $Type: string }>): string {
35
+ const singleKey = valuePairs.length === 1;
36
+ return valuePairs
37
+ .map((valuePair) => {
38
+ const keyValue = valuePair.value;
39
+ const encodedKeyValue =
40
+ typeMetadata[valuePair.name].$Type === "Edm.String" ? `'${encodeURIComponent(keyValue as string)}'` : keyValue;
41
+ return singleKey ? encodedKeyValue : `${valuePair.name}=${encodedKeyValue}`;
42
+ })
43
+ .join(",");
44
+ },
27
45
  getSemanticPath: function (oContext: ODataV4Context, bStrict = false): string | undefined {
28
46
  const oMetaModel = oContext.getModel().getMetaModel(),
29
47
  sEntitySetName = oMetaModel.getMetaContext(oContext.getPath()).getObject("@sapui.name"),
@@ -36,33 +54,27 @@ const SemanticKeyHelper = {
36
54
  sTechnicalPath = oContext.getPath();
37
55
  }
38
56
 
39
- if (this._isPathForSemantic(sTechnicalPath) && oSemanticObjectInformation.semanticKeys) {
57
+ if (
58
+ this._isPathForSemantic(sTechnicalPath) &&
59
+ oSemanticObjectInformation.semanticKeys &&
60
+ oSemanticObjectInformation.semanticKeys.length !== 0
61
+ ) {
40
62
  const aSemanticKeys = oSemanticObjectInformation.semanticKeys;
41
63
  const oEntityType = oMetaModel.getObject("/" + oMetaModel.getObject(`/${sEntitySetName}`).$Type);
42
64
 
43
65
  try {
44
- const sSemanticKeysPart = aSemanticKeys
45
- .map(function (oSemanticKey) {
46
- const sPropertyPath = oSemanticKey.$PropertyPath;
47
- let sKeyValue = oContext.getProperty(sPropertyPath);
48
-
49
- if (sKeyValue === undefined || sKeyValue === null) {
50
- throw new Error(`Couldn't resolve semantic key value for ${sPropertyPath}`);
51
- } else {
52
- if (oEntityType[sPropertyPath].$Type === "Edm.String") {
53
- sKeyValue = `'${encodeURIComponent(sKeyValue)}'`;
54
- }
55
- if (aSemanticKeys.length > 1) {
56
- // Several semantic keys --> path should be entitySet(key1=value1, key2=value2, ...)
57
- // Otherwise we keep entitySet(keyValue)
58
- sKeyValue = `${sPropertyPath}=${sKeyValue}`;
59
- }
60
- return sKeyValue;
61
- }
62
- })
63
- .join(",");
66
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
+ const keyValues = aSemanticKeys.map((semanticKey) => {
68
+ const keyName = semanticKey.$PropertyPath;
69
+ const keyValue = oContext.getProperty(keyName);
70
+ if (keyValue === undefined || keyValue === null) {
71
+ throw new Error(`Couldn't resolve semantic key value for ${keyName}`);
72
+ }
73
+ return { name: keyName, value: keyValue };
74
+ });
75
+ const semanticKeysPart = this.getPathContent(keyValues, oEntityType);
64
76
 
65
- sSemanticPath = `/${sEntitySetName}(${sSemanticKeysPart})`;
77
+ sSemanticPath = `/${sEntitySetName}(${semanticKeysPart})`;
66
78
  } catch (e) {
67
79
  Log.info(e as string);
68
80
  }