@sapui5/sap.fe.core 1.99.0 → 1.100.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 (246) hide show
  1. package/package.json +4 -2
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AnnotationHelper.js +1 -69
  4. package/src/sap/fe/core/AnnotationHelper.ts +0 -70
  5. package/src/sap/fe/core/AppComponent.js +388 -399
  6. package/src/sap/fe/core/AppComponent.ts +403 -0
  7. package/src/sap/fe/core/AppStateHandler.js +127 -158
  8. package/src/sap/fe/core/BaseController.js +82 -58
  9. package/src/sap/fe/core/BaseController.ts +68 -0
  10. package/src/sap/fe/core/CommonUtils.js +111 -20
  11. package/src/sap/fe/core/CommonUtils.ts +131 -32
  12. package/src/sap/fe/core/ExtensionAPI.js +278 -274
  13. package/src/sap/fe/core/ExtensionAPI.ts +250 -0
  14. package/src/sap/fe/core/PageController.js +157 -29
  15. package/src/sap/fe/core/PageController.ts +60 -32
  16. package/src/sap/fe/core/RouterProxy.js +694 -756
  17. package/src/sap/fe/core/RouterProxy.ts +11 -9
  18. package/src/sap/fe/core/Synchronization.js +21 -31
  19. package/src/sap/fe/core/TemplateComponent.js +1 -1
  20. package/src/sap/fe/core/TemplateComponent.ts +10 -3
  21. package/src/sap/fe/core/TemplateModel.js +20 -38
  22. package/src/sap/fe/core/TemplateModel.ts +1 -1
  23. package/src/sap/fe/core/TransactionHelper.js +1354 -1370
  24. package/src/sap/fe/core/TransactionHelper.ts +33 -22
  25. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +392 -0
  26. package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +355 -0
  27. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +136 -0
  28. package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +119 -0
  29. package/src/sap/fe/core/actions/collaboration/Manage.js +262 -0
  30. package/src/sap/fe/core/actions/collaboration/Manage.ts +244 -0
  31. package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +103 -0
  32. package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
  33. package/src/sap/fe/core/actions/draft.js +30 -68
  34. package/src/sap/fe/core/actions/draft.ts +44 -71
  35. package/src/sap/fe/core/actions/messageHandling.js +55 -36
  36. package/src/sap/fe/core/actions/messageHandling.ts +66 -46
  37. package/src/sap/fe/core/actions/operations.js +34 -15
  38. package/src/sap/fe/core/actions/operations.ts +48 -18
  39. package/src/sap/fe/core/actions/sticky.js +17 -4
  40. package/src/sap/fe/core/actions/sticky.ts +21 -4
  41. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +69 -66
  42. package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.ts +65 -0
  43. package/src/sap/fe/core/controllerextensions/EditFlow.js +1593 -1669
  44. package/src/sap/fe/core/controllerextensions/EditFlow.ts +1672 -0
  45. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +79 -54
  46. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +61 -0
  47. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +718 -779
  48. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +783 -0
  49. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +796 -816
  50. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +803 -0
  51. package/src/sap/fe/core/controllerextensions/InternalRouting.js +1004 -1005
  52. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +978 -0
  53. package/src/sap/fe/core/controllerextensions/KPIManagement.js +487 -521
  54. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +2 -2
  55. package/src/sap/fe/core/controllerextensions/MassEdit.js +141 -169
  56. package/src/sap/fe/core/controllerextensions/MassEdit.ts +156 -0
  57. package/src/sap/fe/core/controllerextensions/MessageHandler.js +233 -244
  58. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +225 -0
  59. package/src/sap/fe/core/controllerextensions/PageReady.js +301 -336
  60. package/src/sap/fe/core/controllerextensions/PageReady.ts +12 -10
  61. package/src/sap/fe/core/controllerextensions/Paginator.js +188 -175
  62. package/src/sap/fe/core/controllerextensions/Paginator.ts +163 -0
  63. package/src/sap/fe/core/controllerextensions/Placeholder.js +157 -149
  64. package/src/sap/fe/core/controllerextensions/Placeholder.ts +151 -0
  65. package/src/sap/fe/core/controllerextensions/Routing.js +144 -125
  66. package/src/sap/fe/core/controllerextensions/Routing.ts +132 -0
  67. package/src/sap/fe/core/controllerextensions/RoutingListener.js +7 -6
  68. package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
  69. package/src/sap/fe/core/controllerextensions/Share.js +230 -268
  70. package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
  71. package/src/sap/fe/core/controllerextensions/SideEffects.js +592 -633
  72. package/src/sap/fe/core/controllerextensions/SideEffects.ts +8 -7
  73. package/src/sap/fe/core/controllerextensions/ViewState.js +788 -806
  74. package/src/sap/fe/core/controllerextensions/ViewState.ts +805 -0
  75. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -2
  76. package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
  77. package/src/sap/fe/core/controls/CommandExecution.js +67 -66
  78. package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
  79. package/src/sap/fe/core/controls/ConditionalWrapper.js +90 -75
  80. package/src/sap/fe/core/controls/ConditionalWrapper.ts +83 -0
  81. package/src/sap/fe/core/controls/CustomQuickViewPage.js +130 -125
  82. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +126 -0
  83. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +103 -112
  84. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +101 -0
  85. package/src/sap/fe/core/controls/FieldWrapper.js +122 -135
  86. package/src/sap/fe/core/controls/FieldWrapper.ts +115 -0
  87. package/src/sap/fe/core/controls/FilterBar.js +162 -159
  88. package/src/sap/fe/core/controls/FilterBar.ts +143 -0
  89. package/src/sap/fe/core/controls/FormElementWrapper.js +45 -39
  90. package/src/sap/fe/core/controls/FormElementWrapper.ts +40 -0
  91. package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +37 -42
  92. package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
  93. package/src/sap/fe/core/controls/filterbar/FilterContainer.js +126 -116
  94. package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +98 -0
  95. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +241 -255
  96. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +245 -0
  97. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +150 -141
  98. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
  99. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +335 -322
  100. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
  101. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +74 -74
  102. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +70 -0
  103. package/src/sap/fe/core/converters/ConverterContext.js +348 -379
  104. package/src/sap/fe/core/converters/ConverterContext.ts +19 -16
  105. package/src/sap/fe/core/converters/ManifestSettings.js +12 -1
  106. package/src/sap/fe/core/converters/ManifestSettings.ts +12 -1
  107. package/src/sap/fe/core/converters/ManifestWrapper.js +354 -378
  108. package/src/sap/fe/core/converters/ManifestWrapper.ts +10 -0
  109. package/src/sap/fe/core/converters/MetaModelConverter.js +6 -4
  110. package/src/sap/fe/core/converters/MetaModelConverter.ts +5 -2
  111. package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
  112. package/src/sap/fe/core/converters/TemplateConverter.ts +2 -1
  113. package/src/sap/fe/core/converters/annotations/DataField.js +26 -12
  114. package/src/sap/fe/core/converters/annotations/DataField.ts +37 -13
  115. package/src/sap/fe/core/converters/controls/Common/Form.js +2 -2
  116. package/src/sap/fe/core/converters/controls/Common/Form.ts +4 -2
  117. package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
  118. package/src/sap/fe/core/converters/controls/Common/KPI.ts +3 -2
  119. package/src/sap/fe/core/converters/controls/Common/Table.js +130 -23
  120. package/src/sap/fe/core/converters/controls/Common/Table.ts +134 -29
  121. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +118 -53
  122. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +156 -93
  123. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +161 -207
  124. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +148 -206
  125. package/src/sap/fe/core/converters/helpers/Aggregation.js +115 -133
  126. package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
  127. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
  128. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
  129. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
  130. package/src/sap/fe/core/converters/helpers/Key.js +42 -57
  131. package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
  132. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +25 -4
  133. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +20 -3
  134. package/src/sap/fe/core/converters/templates/ListReportConverter.js +10 -4
  135. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +15 -4
  136. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +7 -5
  137. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +5 -1
  138. package/src/sap/fe/core/designtime/AppComponent.designtime.js +92 -98
  139. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
  140. package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
  141. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
  142. package/src/sap/fe/core/formatters/TableFormatter.js +53 -2
  143. package/src/sap/fe/core/formatters/TableFormatter.ts +51 -0
  144. package/src/sap/fe/core/fpm/Component.js +50 -54
  145. package/src/sap/fe/core/fpm/Component.ts +48 -0
  146. package/src/sap/fe/core/helpers/AppStartupHelper.js +323 -309
  147. package/src/sap/fe/core/helpers/AppStartupHelper.ts +363 -337
  148. package/src/sap/fe/core/helpers/BindingExpression.js +7 -7
  149. package/src/sap/fe/core/helpers/BindingExpression.ts +7 -7
  150. package/src/sap/fe/core/helpers/ClassSupport.js +186 -62
  151. package/src/sap/fe/core/helpers/ClassSupport.ts +168 -52
  152. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +5 -4
  153. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -5
  154. package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
  155. package/src/sap/fe/core/helpers/FPMHelper.ts +1 -1
  156. package/src/sap/fe/core/helpers/MassEditHelper.js +601 -684
  157. package/src/sap/fe/core/helpers/MassEditHelper.ts +699 -0
  158. package/src/sap/fe/core/helpers/ModelHelper.js +25 -1
  159. package/src/sap/fe/core/helpers/ModelHelper.ts +23 -0
  160. package/src/sap/fe/core/helpers/SemanticDateOperators.js +5 -1
  161. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +4 -0
  162. package/src/sap/fe/core/library.js +426 -451
  163. package/src/sap/fe/core/library.support.js +22 -33
  164. package/src/sap/fe/core/library.support.ts +23 -0
  165. package/src/sap/fe/core/library.ts +420 -0
  166. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +5 -3
  167. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +4 -1
  168. package/src/sap/fe/core/messagebundle.properties +22 -5
  169. package/src/sap/fe/core/messagebundle_ar.properties +27 -7
  170. package/src/sap/fe/core/messagebundle_bg.properties +27 -7
  171. package/src/sap/fe/core/messagebundle_ca.properties +27 -7
  172. package/src/sap/fe/core/messagebundle_cs.properties +27 -7
  173. package/src/sap/fe/core/messagebundle_cy.properties +27 -7
  174. package/src/sap/fe/core/messagebundle_da.properties +27 -7
  175. package/src/sap/fe/core/messagebundle_de.properties +27 -7
  176. package/src/sap/fe/core/messagebundle_el.properties +27 -7
  177. package/src/sap/fe/core/messagebundle_en.properties +27 -7
  178. package/src/sap/fe/core/messagebundle_en_GB.properties +27 -7
  179. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +27 -7
  180. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +27 -7
  181. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +27 -7
  182. package/src/sap/fe/core/messagebundle_es.properties +27 -7
  183. package/src/sap/fe/core/messagebundle_es_MX.properties +27 -7
  184. package/src/sap/fe/core/messagebundle_et.properties +27 -7
  185. package/src/sap/fe/core/messagebundle_fi.properties +28 -8
  186. package/src/sap/fe/core/messagebundle_fr.properties +28 -8
  187. package/src/sap/fe/core/messagebundle_fr_CA.properties +29 -9
  188. package/src/sap/fe/core/messagebundle_hi.properties +27 -7
  189. package/src/sap/fe/core/messagebundle_hr.properties +27 -7
  190. package/src/sap/fe/core/messagebundle_hu.properties +27 -7
  191. package/src/sap/fe/core/messagebundle_id.properties +27 -7
  192. package/src/sap/fe/core/messagebundle_it.properties +27 -7
  193. package/src/sap/fe/core/messagebundle_iw.properties +27 -7
  194. package/src/sap/fe/core/messagebundle_ja.properties +26 -6
  195. package/src/sap/fe/core/messagebundle_kk.properties +27 -7
  196. package/src/sap/fe/core/messagebundle_ko.properties +27 -7
  197. package/src/sap/fe/core/messagebundle_lt.properties +27 -7
  198. package/src/sap/fe/core/messagebundle_lv.properties +28 -8
  199. package/src/sap/fe/core/messagebundle_ms.properties +27 -7
  200. package/src/sap/fe/core/messagebundle_nl.properties +27 -7
  201. package/src/sap/fe/core/messagebundle_no.properties +27 -7
  202. package/src/sap/fe/core/messagebundle_pl.properties +27 -7
  203. package/src/sap/fe/core/messagebundle_pt.properties +28 -8
  204. package/src/sap/fe/core/messagebundle_pt_PT.properties +27 -7
  205. package/src/sap/fe/core/messagebundle_ro.properties +27 -7
  206. package/src/sap/fe/core/messagebundle_ru.properties +27 -7
  207. package/src/sap/fe/core/messagebundle_sh.properties +27 -7
  208. package/src/sap/fe/core/messagebundle_sk.properties +27 -7
  209. package/src/sap/fe/core/messagebundle_sl.properties +27 -7
  210. package/src/sap/fe/core/messagebundle_sv.properties +27 -7
  211. package/src/sap/fe/core/messagebundle_th.properties +26 -6
  212. package/src/sap/fe/core/messagebundle_tr.properties +30 -10
  213. package/src/sap/fe/core/messagebundle_uk.properties +27 -7
  214. package/src/sap/fe/core/messagebundle_vi.properties +27 -7
  215. package/src/sap/fe/core/messagebundle_zh_CN.properties +27 -7
  216. package/src/sap/fe/core/messagebundle_zh_TW.properties +27 -7
  217. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +45 -71
  218. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +154 -192
  219. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +4 -4
  220. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +66 -92
  221. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +1 -1
  222. package/src/sap/fe/core/services/NavigationServiceFactory.js +284 -339
  223. package/src/sap/fe/core/services/NavigationServiceFactory.ts +10 -13
  224. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +67 -102
  225. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +5 -2
  226. package/src/sap/fe/core/services/RoutingServiceFactory.js +754 -814
  227. package/src/sap/fe/core/services/RoutingServiceFactory.ts +13 -13
  228. package/src/sap/fe/core/services/ShellServicesFactory.js +649 -736
  229. package/src/sap/fe/core/services/ShellServicesFactory.ts +7 -4
  230. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +567 -592
  231. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +22 -3
  232. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +354 -386
  233. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +21 -14
  234. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +1 -1
  235. package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +1 -1
  236. package/src/sap/fe/core/support/CommonHelper.js +1 -1
  237. package/src/sap/fe/core/support/CommonHelper.ts +1 -1
  238. package/src/sap/fe/core/support/Diagnostics.js +36 -48
  239. package/src/sap/fe/core/templating/DataModelPathHelper.js +93 -85
  240. package/src/sap/fe/core/templating/DataModelPathHelper.ts +104 -95
  241. package/src/sap/fe/core/templating/FilterHelper.js +25 -32
  242. package/src/sap/fe/core/templating/FilterHelper.ts +36 -35
  243. package/src/sap/fe/core/templating/PropertyHelper.js +2 -2
  244. package/src/sap/fe/core/templating/PropertyHelper.ts +1 -1
  245. package/src/sap/fe/core/templating/UIFormatters.js +32 -26
  246. package/src/sap/fe/core/templating/UIFormatters.ts +37 -24
@@ -18,374 +18,400 @@ type PageInfo = {
18
18
  technicalKeys: ValuedKey[] | undefined;
19
19
  semanticKeys: ValuedKey[] | undefined;
20
20
  target: string;
21
+ pageLevel: number;
21
22
  };
22
23
 
23
- /**
24
- * Retrieves a set of key values from startup parameters.
25
- *
26
- * @param aKeyNames The array of key names
27
- * @param oStartupParameters The startup parameters
28
- * @returns An array of pairs {name, value} if all key values could be found in the startup parameters, undefined otherwise
29
- */
30
- function _getKeysFromStartupParams(aKeyNames: string[], oStartupParameters: any): ValuedKey[] | undefined {
31
- let bAllFound = true;
32
- const aKeys = aKeyNames.map(name => {
33
- if (oStartupParameters[name] && oStartupParameters[name].length === 1) {
34
- return { name, value: oStartupParameters[name][0] as string };
35
- } else {
36
- // A unique key value couldn't be found in the startup parameters
37
- bAllFound = false;
38
- return { name, value: "" };
39
- }
40
- });
41
-
42
- return bAllFound ? aKeys : undefined;
43
- }
44
-
45
- /**
46
- * Creates a filter from a list of key values.
47
- *
48
- * @param aKeys Array of semantic keys or technical keys (with values)
49
- * @param bDraftMode True if the entity supports draft mode
50
- * @param oMetaModel The metamodel
51
- * @returns The filter
52
- */
53
- function _createFilterFromKeys(aKeys: ValuedKey[], bDraftMode: Boolean, oMetaModel: ODataMetaModel): Filter {
54
- const bFilterCaseSensitive = ModelHelper.isFilteringCaseSensitive(oMetaModel);
55
-
56
- let bFilterOnActiveEntity = false;
57
- const aFilters = aKeys.map(key => {
58
- if (key.name === "IsActiveEntity") {
59
- bFilterOnActiveEntity = true;
60
- }
61
- return new Filter({
62
- path: key.name,
63
- operator: FilterOperator.EQ,
64
- value1: key.value,
65
- caseSensitive: bFilterCaseSensitive
24
+ const AppStartupHelper = {
25
+ /**
26
+ * Retrieves a set of key values from startup parameters.
27
+ *
28
+ * @param aKeyNames The array of key names
29
+ * @param oStartupParameters The startup parameters
30
+ * @returns {any[]} An array of pairs {name, value} if all key values could be found in the startup parameters, undefined otherwise
31
+ */
32
+ _getKeysFromStartupParams: function(aKeyNames: string[], oStartupParameters: any): ValuedKey[] | undefined {
33
+ let bAllFound = true;
34
+ const aKeys = aKeyNames.map(name => {
35
+ if (oStartupParameters[name] && oStartupParameters[name].length === 1) {
36
+ return { name, value: oStartupParameters[name][0] as string };
37
+ } else {
38
+ // A unique key value couldn't be found in the startup parameters
39
+ bAllFound = false;
40
+ return { name, value: "" };
41
+ }
42
+ });
43
+
44
+ return bAllFound ? aKeys : undefined;
45
+ },
46
+
47
+ /**
48
+ * Creates a filter from a list of key values.
49
+ *
50
+ * @param aKeys Array of semantic keys or technical keys (with values)
51
+ * @param bDraftMode True if the entity supports draft mode
52
+ * @param oMetaModel The metamodel
53
+ * @returns The filter
54
+ */
55
+ _createFilterFromKeys: function(aKeys: ValuedKey[], bDraftMode: Boolean, oMetaModel: ODataMetaModel): Filter {
56
+ const bFilterCaseSensitive = ModelHelper.isFilteringCaseSensitive(oMetaModel);
57
+
58
+ let bFilterOnActiveEntity = false;
59
+ const aFilters = aKeys.map(key => {
60
+ if (key.name === "IsActiveEntity") {
61
+ bFilterOnActiveEntity = true;
62
+ }
63
+ return new Filter({
64
+ path: key.name,
65
+ operator: FilterOperator.EQ,
66
+ value1: key.value,
67
+ caseSensitive: bFilterCaseSensitive
68
+ });
66
69
  });
67
- });
68
- if (bDraftMode && !bFilterOnActiveEntity) {
69
- const oDraftFilter = new Filter({
70
- filters: [new Filter("IsActiveEntity", "EQ", false), new Filter("SiblingEntity/IsActiveEntity", "EQ", null)],
71
- and: false
70
+ if (bDraftMode && !bFilterOnActiveEntity) {
71
+ const oDraftFilter = new Filter({
72
+ filters: [new Filter("IsActiveEntity", "EQ", false), new Filter("SiblingEntity/IsActiveEntity", "EQ", null)],
73
+ and: false
74
+ });
75
+ aFilters.push(oDraftFilter);
76
+ }
77
+
78
+ return new Filter(aFilters, true);
79
+ },
80
+
81
+ /**
82
+ * Loads all contexts for a list of page infos.
83
+ *
84
+ * @param aStartupPages The list of page infos
85
+ * @param oModel The model used to load the contexts
86
+ * @returns A Promise for all contexts
87
+ */
88
+ _requestObjectsFromParameters: function(aStartupPages: PageInfo[], oModel: ODataModel): Promise<Context[][]> {
89
+ // Load the respective objects for all object pages found in aExternallyNavigablePages
90
+ const aContextPromises = aStartupPages.map(pageInfo => {
91
+ const aKeys = pageInfo.semanticKeys || pageInfo.technicalKeys || [];
92
+ const oFilter = this._createFilterFromKeys(aKeys, pageInfo.draftMode, oModel.getMetaModel());
93
+
94
+ // only request a minimum of fields to boost backend performance since this is only used to check if an object exists
95
+ const oListBind = oModel.bindList(pageInfo.contextPath, undefined, undefined, oFilter, {
96
+ "$select": aKeys
97
+ .map(key => {
98
+ return key.name;
99
+ })
100
+ .join(",")
101
+ } as any);
102
+ return oListBind.requestContexts(0, 2);
72
103
  });
73
- aFilters.push(oDraftFilter);
74
- }
75
104
 
76
- return new Filter(aFilters, true);
77
- }
78
-
79
- /**
80
- * Loads all contexts for a list of page infos.
81
- *
82
- * @param aStartupPages The list of page infos
83
- * @param oModel The model used to load the contexts
84
- * @returns A Promise for all contexts
85
- */
86
- function _requestObjectsFromParameters(aStartupPages: PageInfo[], oModel: ODataModel): Promise<Context[][]> {
87
- // Load the respective objects for all object pages found in aExternallyNavigablePages
88
- const aContextPromises = aStartupPages.map(pageInfo => {
89
- const aKeys = pageInfo.semanticKeys || pageInfo.technicalKeys || [];
90
- const oFilter = _createFilterFromKeys(aKeys, pageInfo.draftMode, oModel.getMetaModel());
91
-
92
- // only request a minimum of fields to boost backend performance since this is only used to check if an object exists
93
- const oListBind = oModel.bindList(pageInfo.contextPath, undefined, undefined, oFilter, {
94
- "$select": aKeys
95
- .map(key => {
96
- return key.name;
97
- })
98
- .join(",")
99
- } as any);
100
- return oListBind.requestContexts(0, 2);
101
- });
102
-
103
- return Promise.all(aContextPromises);
104
- }
105
-
106
- /**
107
- * Returns the list of all pages that allow deeplink and that can be reached using the startup parameters.
108
- *
109
- * @param oManifestRouting The routing information from the app manifest
110
- * @param oStartupParameters The startup parameters
111
- * @param oMetaModel The metamodel
112
- * @returns
113
- */
114
- function _getReachablePages(oManifestRouting: any, oStartupParameters: any, oMetaModel: ODataMetaModel): PageInfo[][] {
115
- const aRoutes: any[] = oManifestRouting.routes;
116
- const mPagesByLevel: Record<number, PageInfo[]> = {};
117
-
118
- aRoutes.forEach(oRoute => {
105
+ return Promise.all(aContextPromises);
106
+ },
107
+
108
+ /**
109
+ * Creates a PageInfo from a route if ti's reachable from the startup parameters.
110
+ *
111
+ * @param oRoute The route
112
+ * @param oManifestRouting The app manifest routing section
113
+ * @param oStartupParameters The startup parameters
114
+ * @param oMetaModel The app metamodel
115
+ * @returns A page info if the page is reachable, undefined otherwise
116
+ */
117
+ _getReachablePageInfoFromRoute: function(
118
+ oRoute: any,
119
+ oManifestRouting: any,
120
+ oStartupParameters: any,
121
+ oMetaModel: ODataMetaModel
122
+ ): PageInfo | undefined {
123
+ // Remove trailing ':?query:' and '/'
119
124
  let sPattern: string = oRoute.pattern.replace(":?query:", "");
120
- if (sPattern.endsWith("/")) {
121
- sPattern = sPattern.substr(0, sPattern.length - 1);
125
+ sPattern = sPattern.replace(/\/$/, "");
126
+
127
+ if (!sPattern) {
128
+ return undefined; // Ignore level-0 routes (ListReport)
122
129
  }
123
130
 
124
- if (sPattern) {
125
- // Ignore level-0 routes (ListReport)
126
- sPattern = sPattern.replace(/\(\{[^\}]*\}\)/g, "(#)"); // Replace keys with #
131
+ sPattern = sPattern.replace(/\(\{[^\}]*\}\)/g, "(#)"); // Replace keys with #
127
132
 
128
- // Get the rightmost target for this route
129
- const sTargetName: string = Array.isArray(oRoute.target) ? oRoute.target[oRoute.target.length - 1] : oRoute.target;
130
- const oTarget = oManifestRouting.targets[sTargetName];
133
+ // Get the rightmost target for this route
134
+ const sTargetName: string = Array.isArray(oRoute.target) ? oRoute.target[oRoute.target.length - 1] : oRoute.target;
135
+ const oTarget = oManifestRouting.targets[sTargetName];
131
136
 
132
- const aPatternSegments = sPattern.split("/");
133
- const pageLevel = aPatternSegments.length - 1;
137
+ const aPatternSegments = sPattern.split("/");
138
+ const pageLevel = aPatternSegments.length - 1;
134
139
 
140
+ if (pageLevel !== 0 && oTarget?.options?.settings?.allowDeepLinking !== true) {
135
141
  // The first level of object page allows deep linking by default.
136
142
  // Otherwise, the target must allow deep linking explicitely in the manifest
137
- if (pageLevel === 0 || oTarget?.options?.settings?.allowDeepLinking) {
138
- const sContextPath: string =
139
- oTarget.options.settings.contextPath ||
140
- (oTarget.options.settings.entitySet && "/" + oTarget.options.settings.entitySet);
141
- const oEntityType = sContextPath && oMetaModel.getObject("/$EntityContainer" + sContextPath + "/");
142
-
143
- if (oEntityType) {
144
- // Get the semantic key values for the entity
145
- const aSemanticKeyNames: any = oMetaModel.getObject(
146
- "/$EntityContainer" + sContextPath + "/@com.sap.vocabularies.Common.v1.SemanticKey"
147
- );
148
- const aSemantickKeys = aSemanticKeyNames
149
- ? _getKeysFromStartupParams(
150
- aSemanticKeyNames.map((semKey: any) => {
151
- return semKey.$PropertyPath as string;
152
- }),
153
- oStartupParameters
154
- )
155
- : undefined;
156
-
157
- // Get the technical keys only if we couldn't find the semantic key values, and on first level OP
158
- const aTechnicalKeys =
159
- !aSemantickKeys && pageLevel === 0 ? _getKeysFromStartupParams(oEntityType["$Key"], oStartupParameters) : undefined;
160
-
161
- if (aSemantickKeys || aTechnicalKeys) {
162
- // The startup parameters contain values for all semantic keys (or technical keys) --> we can store the page info in the corresponding level
163
- const draftMode =
164
- oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot") ||
165
- oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftNode")
166
- ? true
167
- : false;
168
-
169
- if (!mPagesByLevel[pageLevel]) {
170
- mPagesByLevel[pageLevel] = [];
171
- }
172
- mPagesByLevel[pageLevel].push({
173
- pattern: sPattern,
174
- contextPath: sContextPath,
175
- draftMode,
176
- technicalKeys: aTechnicalKeys,
177
- semanticKeys: aSemantickKeys,
178
- target: sTargetName
179
- });
180
- }
181
- }
182
- }
143
+ return undefined;
183
144
  }
184
- });
185
-
186
- // A page is reachable only if all its parents are also reachable
187
- // So if we couldn't find any pages for a given level, all pages with a higher level won't be reachable anyway
188
- const aReachablePages: PageInfo[][] = [];
189
- let level = 0;
190
- while (mPagesByLevel[level]) {
191
- aReachablePages.push(mPagesByLevel[level]);
192
- level++;
193
- }
194
145
 
195
- return aReachablePages;
196
- }
197
-
198
- /**
199
- * Get the list of startup pages.
200
- *
201
- * @param oManifestRouting The routing information from the app manifest
202
- * @param oStartupParameters The startup parameters
203
- * @param oMetaModel The metamodel
204
- * @returns An array of startup page infos
205
- */
206
- function _getStartupPagesFromStartupParams(oManifestRouting: any, oStartupParameters: any, oMetaModel: ODataMetaModel): PageInfo[] {
207
- // Find all pages that can be reached with the startup parameters
208
- const aReachablePages = _getReachablePages(oManifestRouting, oStartupParameters, oMetaModel);
209
-
210
- if (aReachablePages.length === 0) {
211
- return [];
212
- }
146
+ const sContextPath: string =
147
+ oTarget.options.settings.contextPath || (oTarget.options.settings.entitySet && "/" + oTarget.options.settings.entitySet);
148
+ const oEntityType = sContextPath && oMetaModel.getObject("/$EntityContainer" + sContextPath + "/");
213
149
 
214
- // Find the longest sequence of pages that can be reached (recursively)
215
- let result: PageInfo[] = [];
216
- const current: PageInfo[] = [];
217
-
218
- function findRecursive(level: number) {
219
- const aCurrentLevelPages = aReachablePages[level];
220
- const lastPage = current.length ? current[current.length - 1] : undefined;
221
-
222
- if (aCurrentLevelPages) {
223
- aCurrentLevelPages.forEach(function(nextPage) {
224
- if (!lastPage || nextPage.pattern.indexOf(lastPage.pattern) === 0) {
225
- // We only consider pages that can be reached from the page at the previous level,
226
- // --> their pattern must be the pattern of the previous page with another segment appended
227
- current.push(nextPage);
228
- findRecursive(level + 1);
229
- current.pop();
230
- }
231
- });
150
+ if (!oEntityType) {
151
+ return undefined;
232
152
  }
233
- if (current.length > result.length) {
234
- result = current.slice(); // We have found a sequence longer than our previous best --> store it as the new longest
153
+
154
+ // Get the semantic key values for the entity
155
+ const aSemanticKeyNames: any = oMetaModel.getObject(
156
+ "/$EntityContainer" + sContextPath + "/@com.sap.vocabularies.Common.v1.SemanticKey"
157
+ );
158
+
159
+ const aSemantickKeys = aSemanticKeyNames
160
+ ? this._getKeysFromStartupParams(
161
+ aSemanticKeyNames.map((semKey: any) => {
162
+ return semKey.$PropertyPath as string;
163
+ }),
164
+ oStartupParameters
165
+ )
166
+ : undefined;
167
+
168
+ // Get the technical keys only if we couldn't find the semantic key values, and on first level OP
169
+ const aTechnicalKeys =
170
+ !aSemantickKeys && pageLevel === 0 ? this._getKeysFromStartupParams(oEntityType["$Key"], oStartupParameters) : undefined;
171
+
172
+ if (aSemantickKeys === undefined && aTechnicalKeys === undefined) {
173
+ // We couldn't find the semantic/technical keys in the startup parameters
174
+ return undefined;
235
175
  }
236
- }
237
176
 
238
- findRecursive(0);
239
-
240
- return result;
241
- }
242
-
243
- /**
244
- * Creates the startup object from the list of pages and contexts.
245
- *
246
- * @param aStartupPages The pages
247
- * @param aContexts The contexts
248
- * @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
249
- */
250
- function _getDeepLinkObject(aStartupPages: PageInfo[], aContexts: Context[]): { hash?: string; context?: Context } {
251
- if (aContexts.length === 1) {
252
- return { context: aContexts[0] };
253
- } else if (aContexts.length > 1) {
254
- // Navigation to a deeper level --> use the pattern of the deepest object page
255
- // and replace the parameters by the ID from the contexts
256
- let hash = aStartupPages[aStartupPages.length - 1].pattern;
257
- aContexts.forEach(function(oContext) {
258
- hash = hash.replace("(#)", "(" + oContext.getPath().split("(")[1]);
177
+ // The startup parameters contain values for all semantic keys (or technical keys) --> we can store the page info in the corresponding level
178
+ const draftMode =
179
+ oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot") ||
180
+ oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftNode")
181
+ ? true
182
+ : false;
183
+
184
+ return {
185
+ pattern: sPattern,
186
+ contextPath: sContextPath,
187
+ draftMode,
188
+ technicalKeys: aTechnicalKeys,
189
+ semanticKeys: aSemantickKeys,
190
+ target: sTargetName,
191
+ pageLevel
192
+ };
193
+ },
194
+
195
+ /**
196
+ * Returns the list of all pages that allow deeplink and that can be reached using the startup parameters.
197
+ *
198
+ * @param oManifestRouting The routing information from the app manifest
199
+ * @param oStartupParameters The startup parameters
200
+ * @param oMetaModel The metamodel
201
+ * @returns
202
+ */
203
+ _getReachablePages: function(oManifestRouting: any, oStartupParameters: any, oMetaModel: ODataMetaModel): PageInfo[][] {
204
+ const aRoutes: any[] = oManifestRouting.routes;
205
+ const mPagesByLevel: Record<number, PageInfo[]> = {};
206
+
207
+ aRoutes.forEach(oRoute => {
208
+ const oPageInfo = this._getReachablePageInfoFromRoute(oRoute, oManifestRouting, oStartupParameters, oMetaModel);
209
+
210
+ if (oPageInfo) {
211
+ if (!mPagesByLevel[oPageInfo.pageLevel]) {
212
+ mPagesByLevel[oPageInfo.pageLevel] = [];
213
+ }
214
+ mPagesByLevel[oPageInfo.pageLevel].push(oPageInfo);
215
+ }
259
216
  });
260
217
 
261
- return { hash };
262
- } else {
263
- return {};
264
- }
265
- }
266
-
267
- /**
268
- * Calculates startup parameters for a deeplink case, from startup parameters and routing infoirmation.
269
- *
270
- * @param oManifestRouting The routing information from the app manifest
271
- * @param oStartupParameters The startup parameters
272
- * @param oModel The OData model
273
- * @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
274
- */
275
- function getDeepLinkStartupHash(
276
- oManifestRouting: any,
277
- oStartupParameters: any,
278
- oModel: ODataModel
279
- ): Promise<{ hash?: string; context?: Context }> {
280
- let aStartupPages: PageInfo[];
281
-
282
- return oModel
283
- .getMetaModel()
284
- .requestObject("/$EntityContainer/")
285
- .then(() => {
286
- // Check if semantic keys are present in url parameters for every object page at each level
287
- aStartupPages = _getStartupPagesFromStartupParams(oManifestRouting, oStartupParameters, oModel.getMetaModel());
288
-
289
- return _requestObjectsFromParameters(aStartupPages, oModel);
290
- })
291
- .then((aValues: Context[][]) => {
292
- if (aValues.length) {
293
- // Make sure we only get 1 context per promise, and flatten the array
294
- const aContexts: Context[] = [];
295
- aValues.forEach(function(aFoundContexts) {
296
- if (aFoundContexts.length === 1) {
297
- aContexts.push(aFoundContexts[0]);
218
+ // A page is reachable only if all its parents are also reachable
219
+ // So if we couldn't find any pages for a given level, all pages with a higher level won't be reachable anyway
220
+ const aReachablePages: PageInfo[][] = [];
221
+ let level = 0;
222
+ while (mPagesByLevel[level]) {
223
+ aReachablePages.push(mPagesByLevel[level]);
224
+ level++;
225
+ }
226
+
227
+ return aReachablePages;
228
+ },
229
+
230
+ /**
231
+ * Get the list of startup pages.
232
+ *
233
+ * @param oManifestRouting The routing information from the app manifest
234
+ * @param oStartupParameters The startup parameters
235
+ * @param oMetaModel The metamodel
236
+ * @returns An array of startup page infos
237
+ */
238
+ _getStartupPagesFromStartupParams: function(oManifestRouting: any, oStartupParameters: any, oMetaModel: ODataMetaModel): PageInfo[] {
239
+ // Find all pages that can be reached with the startup parameters
240
+ const aReachablePages = this._getReachablePages(oManifestRouting, oStartupParameters, oMetaModel);
241
+
242
+ if (aReachablePages.length === 0) {
243
+ return [];
244
+ }
245
+
246
+ // Find the longest sequence of pages that can be reached (recursively)
247
+ let result: PageInfo[] = [];
248
+ const current: PageInfo[] = [];
249
+
250
+ function findRecursive(level: number) {
251
+ const aCurrentLevelPages = aReachablePages[level];
252
+ const lastPage = current.length ? current[current.length - 1] : undefined;
253
+
254
+ if (aCurrentLevelPages) {
255
+ aCurrentLevelPages.forEach(function(nextPage) {
256
+ if (!lastPage || nextPage.pattern.indexOf(lastPage.pattern) === 0) {
257
+ // We only consider pages that can be reached from the page at the previous level,
258
+ // --> their pattern must be the pattern of the previous page with another segment appended
259
+ current.push(nextPage);
260
+ findRecursive(level + 1);
261
+ current.pop();
298
262
  }
299
263
  });
300
-
301
- return aContexts.length === aValues.length ? _getDeepLinkObject(aStartupPages, aContexts) : {};
302
- } else {
303
- return {};
304
264
  }
305
- });
306
- }
307
-
308
- /**
309
- * Calculates the new hash based on the startup parameters.
310
- *
311
- * @param oStartupParameters The startup parameter values (map parameter name -> array of values)
312
- * @param sContextPath The context path for the startup of the app (generally the path to the main entity set)
313
- * @param oRouter The router instance
314
- * @param oMetaModel The meta model
315
- * @returns A promise containing the hash to navigate to, or an empty string if there's no need to navigate
316
- */
317
- function getCreateStartupHash(oStartupParameters: any, sContextPath: string, oRouter: Router, oMetaModel: ODataMetaModel): Promise<String> {
318
- return oMetaModel.requestObject(sContextPath + "@").then(function(oEntitySetAnnotations: any) {
319
- let sMetaPath = "";
320
- let bCreatable = true;
321
-
322
- if (
323
- oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"] &&
324
- oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"]["NewAction"]
325
- ) {
326
- sMetaPath = sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction@Org.OData.Core.V1.OperationAvailable";
327
- } else if (
328
- oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"] &&
329
- oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"]["NewAction"]
330
- ) {
331
- sMetaPath =
332
- sContextPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction@Org.OData.Core.V1.OperationAvailable";
265
+ if (current.length > result.length) {
266
+ result = current.slice(); // We have found a sequence longer than our previous best --> store it as the new longest
267
+ }
333
268
  }
334
269
 
335
- if (sMetaPath) {
336
- const bNewActionOperationAvailable = oMetaModel.getObject(sMetaPath);
337
- if (bNewActionOperationAvailable === false) {
338
- bCreatable = false;
339
- }
270
+ findRecursive(0);
271
+
272
+ return result;
273
+ },
274
+
275
+ /**
276
+ * Creates the startup object from the list of pages and contexts.
277
+ *
278
+ * @param aStartupPages The pages
279
+ * @param aContexts The contexts
280
+ * @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
281
+ */
282
+ _getDeepLinkObject: function(aStartupPages: PageInfo[], aContexts: Context[]): { hash?: string; context?: Context } {
283
+ if (aContexts.length === 1) {
284
+ return { context: aContexts[0] };
285
+ } else if (aContexts.length > 1) {
286
+ // Navigation to a deeper level --> use the pattern of the deepest object page
287
+ // and replace the parameters by the ID from the contexts
288
+ let hash = aStartupPages[aStartupPages.length - 1].pattern;
289
+ aContexts.forEach(function(oContext) {
290
+ hash = hash.replace("(#)", "(" + oContext.getPath().split("(")[1]);
291
+ });
292
+
293
+ return { hash };
340
294
  } else {
341
- const oInsertRestrictions = oEntitySetAnnotations["@Org.OData.Capabilities.V1.InsertRestrictions"];
342
- if (oInsertRestrictions && oInsertRestrictions.Insertable === false) {
343
- bCreatable = false;
344
- }
295
+ return {};
345
296
  }
346
- if (bCreatable) {
347
- return getDefaultCreateHash(oStartupParameters, sContextPath, oRouter);
297
+ },
298
+
299
+ /**
300
+ * Calculates startup parameters for a deeplink case, from startup parameters and routing infoirmation.
301
+ *
302
+ * @param oManifestRouting The routing information from the app manifest
303
+ * @param oStartupParameters The startup parameters
304
+ * @param oModel The OData model
305
+ * @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
306
+ */
307
+ getDeepLinkStartupHash: function(
308
+ oManifestRouting: any,
309
+ oStartupParameters: any,
310
+ oModel: ODataModel
311
+ ): Promise<{ hash?: string; context?: Context }> {
312
+ let aStartupPages: PageInfo[];
313
+
314
+ return oModel
315
+ .getMetaModel()
316
+ .requestObject("/$EntityContainer/")
317
+ .then(() => {
318
+ // Check if semantic keys are present in url parameters for every object page at each level
319
+ aStartupPages = this._getStartupPagesFromStartupParams(oManifestRouting, oStartupParameters, oModel.getMetaModel());
320
+
321
+ return this._requestObjectsFromParameters(aStartupPages, oModel);
322
+ })
323
+ .then((aValues: Context[][]) => {
324
+ if (aValues.length) {
325
+ // Make sure we only get 1 context per promise, and flatten the array
326
+ const aContexts: Context[] = [];
327
+ aValues.forEach(function(aFoundContexts) {
328
+ if (aFoundContexts.length === 1) {
329
+ aContexts.push(aFoundContexts[0]);
330
+ }
331
+ });
332
+
333
+ return aContexts.length === aValues.length ? this._getDeepLinkObject(aStartupPages, aContexts) : {};
334
+ } else {
335
+ return {};
336
+ }
337
+ });
338
+ },
339
+
340
+ /**
341
+ * Calculates the new hash based on the startup parameters.
342
+ *
343
+ * @param oStartupParameters The startup parameter values (map parameter name -> array of values)
344
+ * @param sContextPath The context path for the startup of the app (generally the path to the main entity set)
345
+ * @param oRouter The router instance
346
+ * @param oMetaModel The meta model
347
+ * @returns A promise containing the hash to navigate to, or an empty string if there's no need to navigate
348
+ */
349
+ getCreateStartupHash: function(
350
+ oStartupParameters: any,
351
+ sContextPath: string,
352
+ oRouter: Router,
353
+ oMetaModel: ODataMetaModel
354
+ ): Promise<String> {
355
+ return oMetaModel.requestObject(sContextPath + "@").then((oEntitySetAnnotations: any) => {
356
+ let sMetaPath = "";
357
+ let bCreatable = true;
358
+
359
+ if (
360
+ oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"] &&
361
+ oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"]["NewAction"]
362
+ ) {
363
+ sMetaPath = sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction@Org.OData.Core.V1.OperationAvailable";
364
+ } else if (
365
+ oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"] &&
366
+ oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"]["NewAction"]
367
+ ) {
368
+ sMetaPath =
369
+ sContextPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction@Org.OData.Core.V1.OperationAvailable";
370
+ }
371
+
372
+ if (sMetaPath) {
373
+ const bNewActionOperationAvailable = oMetaModel.getObject(sMetaPath);
374
+ if (bNewActionOperationAvailable === false) {
375
+ bCreatable = false;
376
+ }
377
+ } else {
378
+ const oInsertRestrictions = oEntitySetAnnotations["@Org.OData.Capabilities.V1.InsertRestrictions"];
379
+ if (oInsertRestrictions && oInsertRestrictions.Insertable === false) {
380
+ bCreatable = false;
381
+ }
382
+ }
383
+ if (bCreatable) {
384
+ return this.getDefaultCreateHash(oStartupParameters, sContextPath, oRouter);
385
+ } else {
386
+ return "";
387
+ }
388
+ });
389
+ },
390
+
391
+ /**
392
+ * Calculates the hash to create a new object.
393
+ *
394
+ * @param oStartupParameters The startup parameter values (map parameter name -> array of values)
395
+ * @param sContextPath The context path of the entity set to be used for the creation
396
+ * @param oRouter The router instance
397
+ * @returns The hash
398
+ */
399
+ getDefaultCreateHash: function(oStartupParameters: any, sContextPath: string, oRouter: Router): string {
400
+ let sDefaultCreateHash =
401
+ oStartupParameters && oStartupParameters.preferredMode ? (oStartupParameters.preferredMode[0] as string) : "create";
402
+ let sHash = "";
403
+
404
+ sDefaultCreateHash =
405
+ sDefaultCreateHash.indexOf(":") !== -1 && sDefaultCreateHash.length > sDefaultCreateHash.indexOf(":") + 1
406
+ ? sDefaultCreateHash.substr(0, sDefaultCreateHash.indexOf(":"))
407
+ : "create";
408
+ sHash = sContextPath.substring(1) + "(...)?i-action=" + sDefaultCreateHash;
409
+ if (oRouter.getRouteInfoByHash(sHash)) {
410
+ return sHash;
348
411
  } else {
349
- return "";
412
+ throw new Error("No route match for creating a new " + sContextPath.substring(1));
350
413
  }
351
- });
352
- }
353
-
354
- /**
355
- * Calculates the hash to create a new object.
356
- *
357
- * @param oStartupParameters The startup parameter values (map parameter name -> array of values)
358
- * @param sContextPath The context path of the entity set to be used for the creation
359
- * @param oRouter The router instance
360
- * @returns The hash
361
- */
362
- function getDefaultCreateHash(oStartupParameters: any, sContextPath: string, oRouter: Router): string {
363
- let sDefaultCreateHash =
364
- oStartupParameters && oStartupParameters.preferredMode ? (oStartupParameters.preferredMode[0] as string) : "create";
365
- let sHash = "";
366
-
367
- sDefaultCreateHash =
368
- sDefaultCreateHash.indexOf(":") !== -1 && sDefaultCreateHash.length > sDefaultCreateHash.indexOf(":") + 1
369
- ? sDefaultCreateHash.substr(0, sDefaultCreateHash.indexOf(":"))
370
- : "create";
371
- sHash = sContextPath.substring(1) + "(...)?i-action=" + sDefaultCreateHash;
372
- if (oRouter.getRouteInfoByHash(sHash)) {
373
- return sHash;
374
- } else {
375
- throw new Error("No route match for creating a new " + sContextPath.substring(1));
376
414
  }
377
- }
378
-
379
- const AppStartupHelper = {
380
- _getKeysFromStartupParams,
381
- _createFilterFromKeys,
382
- _requestObjectsFromParameters,
383
- _getReachablePages,
384
- _getStartupPagesFromStartupParams,
385
- _getDeepLinkObject,
386
- getDeepLinkStartupHash,
387
- getCreateStartupHash,
388
- getDefaultCreateHash
389
415
  };
390
416
 
391
417
  export default AppStartupHelper;