@sapui5/sap.ushell 1.129.1 → 1.130.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. package/package.json +1 -1
  2. package/src/main/js/sap/ushell/.library +1 -1
  3. package/src/main/js/sap/ushell/AppInfoParameters.js +478 -346
  4. package/src/main/js/sap/ushell/ApplicationType/urlTemplateResolution.js +41 -6
  5. package/src/main/js/sap/ushell/ApplicationType/wdaResolution.js +3 -3
  6. package/src/main/js/sap/ushell/Fiori20Adapter.js +1 -1
  7. package/src/main/js/sap/ushell/Fiori20AdapterTest.js +1 -1
  8. package/src/main/js/sap/ushell/NWBCInterface.js +1 -1
  9. package/src/main/js/sap/ushell/TechnicalParameters.js +1 -1
  10. package/src/main/js/sap/ushell/URLTemplateProcessor/DefinitionParameterSetBuilder.js +1 -1
  11. package/src/main/js/sap/ushell/URLTemplateProcessor/DependencyGraph.js +1 -1
  12. package/src/main/js/sap/ushell/URLTemplateProcessor/Functions.js +1 -1
  13. package/src/main/js/sap/ushell/URLTemplateProcessor/Resolvers.js +1 -1
  14. package/src/main/js/sap/ushell/URLTemplateProcessor/TemplateParameterParser.js +1 -1
  15. package/src/main/js/sap/ushell/URLTemplateProcessor/utils.js +1 -1
  16. package/src/main/js/sap/ushell/URLTemplateProcessor.js +1 -1
  17. package/src/main/js/sap/ushell/Ui5NativeServiceFactory.js +1 -1
  18. package/src/main/js/sap/ushell/Ui5ServiceFactory.js +1 -1
  19. package/src/main/js/sap/ushell/adapters/cdm/ClientSideTargetResolutionAdapter.js +1 -1
  20. package/src/main/js/sap/ushell/adapters/cdm/CommonDataModelAdapter.js +1 -1
  21. package/src/main/js/sap/ushell/adapters/cdm/ConfigurationDefaultsAdapter.js +1 -1
  22. package/src/main/js/sap/ushell/adapters/cdm/ContainerAdapter.js +1 -1
  23. package/src/main/js/sap/ushell/adapters/cdm/LaunchPageAdapter.js +1 -1
  24. package/src/main/js/sap/ushell/adapters/cdm/PagesCommonDataModelAdapter.js +1 -1
  25. package/src/main/js/sap/ushell/adapters/cdm/PersonalizationAdapter.js +1 -1
  26. package/src/main/js/sap/ushell/adapters/cdm/PersonalizationV2Adapter.js +1 -1
  27. package/src/main/js/sap/ushell/adapters/cdm/Ui5ComponentLoaderAdapter.js +1 -1
  28. package/src/main/js/sap/ushell/adapters/cdm/_LaunchPage/modifyHome.js +1 -1
  29. package/src/main/js/sap/ushell/adapters/cdm/_LaunchPage/readCatalogs.js +1 -1
  30. package/src/main/js/sap/ushell/adapters/cdm/_LaunchPage/readHome.js +1 -1
  31. package/src/main/js/sap/ushell/adapters/cdm/_LaunchPage/uri.transform.js +1 -1
  32. package/src/main/js/sap/ushell/adapters/cdm/util/AppForInbound.js +1 -1
  33. package/src/main/js/sap/ushell/adapters/cdm/util/cdmSiteUtils.js +1 -1
  34. package/src/main/js/sap/ushell/adapters/cdm/v3/AdapterBase.js +1 -1
  35. package/src/main/js/sap/ushell/adapters/cdm/v3/FlpLaunchPageAdapter.js +7 -3
  36. package/src/main/js/sap/ushell/adapters/cdm/v3/LaunchPageAdapter.js +1 -1
  37. package/src/main/js/sap/ushell/adapters/cdm/v3/StaticGroupsAdapter.js +1 -1
  38. package/src/main/js/sap/ushell/adapters/cdm/v3/_LaunchPage/readApplications.js +1 -1
  39. package/src/main/js/sap/ushell/adapters/cdm/v3/_LaunchPage/readCatalogs.js +1 -1
  40. package/src/main/js/sap/ushell/adapters/cdm/v3/_LaunchPage/readHome.js +1 -1
  41. package/src/main/js/sap/ushell/adapters/cdm/v3/_LaunchPage/readPages.js +1 -1
  42. package/src/main/js/sap/ushell/adapters/cdm/v3/_LaunchPage/readUtils.js +1 -1
  43. package/src/main/js/sap/ushell/adapters/cdm/v3/_LaunchPage/readVisualizations.js +1 -1
  44. package/src/main/js/sap/ushell/adapters/cep/NavTargetResolutionAdapter.js +1 -1
  45. package/src/main/js/sap/ushell/adapters/cep/NavTargetResolutionInternalAdapter.js +1 -1
  46. package/src/main/js/sap/ushell/adapters/cep/SearchCEPAdapter.js +1 -1
  47. package/src/main/js/sap/ushell/adapters/cflp/UserDefaultParameterPersistenceAdapter.js +1 -1
  48. package/src/main/js/sap/ushell/adapters/local/AdapterContainer.js +1 -1
  49. package/src/main/js/sap/ushell/adapters/local/AppStateAdapter.js +1 -1
  50. package/src/main/js/sap/ushell/adapters/local/ClientSideTargetResolutionAdapter.js +1 -1
  51. package/src/main/js/sap/ushell/adapters/local/ContainerAdapter.js +1 -1
  52. package/src/main/js/sap/ushell/adapters/local/FlpLaunchPageAdapter.js +1 -1
  53. package/src/main/js/sap/ushell/adapters/local/LaunchPageAdapter.js +1 -1
  54. package/src/main/js/sap/ushell/adapters/local/NavTargetResolutionAdapter.js +1 -1
  55. package/src/main/js/sap/ushell/adapters/local/NavTargetResolutionInternalAdapter.js +1 -1
  56. package/src/main/js/sap/ushell/adapters/local/PageBuildingAdapter.js +1 -1
  57. package/src/main/js/sap/ushell/adapters/local/PagePersistenceAdapter.js +1 -1
  58. package/src/main/js/sap/ushell/adapters/local/PersonalizationAdapter.js +1 -1
  59. package/src/main/js/sap/ushell/adapters/local/PersonalizationV2Adapter.js +1 -1
  60. package/src/main/js/sap/ushell/adapters/local/SearchAdapter.js +1 -1
  61. package/src/main/js/sap/ushell/adapters/local/SearchCEPAdapter.js +1 -1
  62. package/src/main/js/sap/ushell/adapters/local/SupportTicketAdapter.js +1 -1
  63. package/src/main/js/sap/ushell/adapters/local/Ui5ComponentLoaderAdapter.js +1 -1
  64. package/src/main/js/sap/ushell/adapters/local/UserDefaultParameterPersistenceAdapter.js +1 -1
  65. package/src/main/js/sap/ushell/adapters/local/UserInfoAdapter.js +1 -1
  66. package/src/main/js/sap/ushell/api/S4MyHome.js +33 -2
  67. package/src/main/js/sap/ushell/appRuntime/ui5/AppRuntime.js +8 -0
  68. package/src/main/js/sap/ushell/appRuntime/ui5/renderers/fiori2/RendererExtensions.js +1 -1
  69. package/src/main/js/sap/ushell/appRuntime/ui5/services/AppConfiguration.js +1 -1
  70. package/src/main/js/sap/ushell/appRuntime/ui5/services/AppLifeCycle.js +1 -1
  71. package/src/main/js/sap/ushell/appRuntime/ui5/services/AppState.js +1 -1
  72. package/src/main/js/sap/ushell/appRuntime/ui5/services/Bookmark.js +1 -1
  73. package/src/main/js/sap/ushell/appRuntime/ui5/services/BookmarkV2.js +1 -1
  74. package/src/main/js/sap/ushell/appRuntime/ui5/services/CommonDataModel.js +1 -1
  75. package/src/main/js/sap/ushell/appRuntime/ui5/services/Container.js +1 -1
  76. package/src/main/js/sap/ushell/appRuntime/ui5/services/CrossApplicationNavigation.js +1 -1
  77. package/src/main/js/sap/ushell/appRuntime/ui5/services/Extension/Item.js +1 -1
  78. package/src/main/js/sap/ushell/appRuntime/ui5/services/Extension.js +1 -1
  79. package/src/main/js/sap/ushell/appRuntime/ui5/services/FrameBoundExtension.js +1 -1
  80. package/src/main/js/sap/ushell/appRuntime/ui5/services/LaunchPage.js +1 -1
  81. package/src/main/js/sap/ushell/appRuntime/ui5/services/MessageBroker.js +1 -1
  82. package/src/main/js/sap/ushell/appRuntime/ui5/services/NavTargetResolution.js +1 -1
  83. package/src/main/js/sap/ushell/appRuntime/ui5/services/NavTargetResolutionInternal.js +1 -1
  84. package/src/main/js/sap/ushell/appRuntime/ui5/services/Navigation.js +1 -1
  85. package/src/main/js/sap/ushell/appRuntime/ui5/services/ReferenceResolver.js +1 -1
  86. package/src/main/js/sap/ushell/appRuntime/ui5/services/ShellNavigation.js +1 -1
  87. package/src/main/js/sap/ushell/appRuntime/ui5/services/ShellNavigationInternal.js +1 -1
  88. package/src/main/js/sap/ushell/appRuntime/ui5/services/ShellUIService.js +1 -1
  89. package/src/main/js/sap/ushell/appRuntime/ui5/services/UserInfo.js +1 -1
  90. package/src/main/js/sap/ushell/appRuntime/ui5/services/adapters/Ui5ComponentLoaderAdapter.js +1 -1
  91. package/src/main/js/sap/ushell/bootstrap/SchedulingAgent/logger.js +1 -1
  92. package/src/main/js/sap/ushell/bootstrap/SchedulingAgent/state.js +1 -1
  93. package/src/main/js/sap/ushell/bootstrap/common/common.configure.ui5datetimeformat.js +1 -1
  94. package/src/main/js/sap/ushell/bootstrap/sandbox2.js +1 -1
  95. package/src/main/js/sap/ushell/components/appfinder/manifest.json +1 -1
  96. package/src/main/js/sap/ushell/components/applicationIntegration/AppLifeCycle.js +871 -733
  97. package/src/main/js/sap/ushell/components/applicationIntegration/application/Application.js +50 -50
  98. package/src/main/js/sap/ushell/components/applicationIntegration/application/BlueBoxHandler.js +121 -116
  99. package/src/main/js/sap/ushell/components/applicationIntegration/application/BlueBoxesCache.js +16 -12
  100. package/src/main/js/sap/ushell/components/applicationIntegration/application/PostMessageAPI.js +2 -4
  101. package/src/main/js/sap/ushell/components/applicationIntegration/application/WebGUIStatefulHandler.js +48 -53
  102. package/src/main/js/sap/ushell/components/applicationIntegration/configuration/AppMeta.js +1 -1
  103. package/src/main/js/sap/ushell/components/applicationIntegration/relatedServices/RelatedServices.js +2 -1
  104. package/src/main/js/sap/ushell/components/container/ApplicationContainer.js +2 -2
  105. package/src/main/js/sap/ushell/components/contentFinder/CatalogService.js +26 -5
  106. package/src/main/js/sap/ushell/components/contentFinder/Component.js +20 -13
  107. package/src/main/js/sap/ushell/components/contentFinder/controller/AppSearch.controller.js +28 -35
  108. package/src/main/js/sap/ushell/components/contentFinder/controller/ContentFinderDialog.controller.js +1 -1
  109. package/src/main/js/sap/ushell/components/contentFinder/controller/WidgetGallery.controller.js +1 -1
  110. package/src/main/js/sap/ushell/components/contentFinder/manifest.json +1 -1
  111. package/src/main/js/sap/ushell/components/contentFinder/model/formatter.js +60 -5
  112. package/src/main/js/sap/ushell/components/contentFinder/resources/resources.properties +17 -6
  113. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_ar.properties +6 -0
  114. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_bg.properties +6 -0
  115. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_ca.properties +6 -0
  116. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_cnr.properties +6 -0
  117. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_cs.properties +6 -0
  118. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_cy.properties +6 -0
  119. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_da.properties +6 -0
  120. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_de.properties +6 -0
  121. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_el.properties +6 -0
  122. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_en.properties +6 -0
  123. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_en_GB.properties +6 -0
  124. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_en_US_saprigi.properties +11 -3
  125. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_es.properties +6 -0
  126. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_es_MX.properties +6 -0
  127. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_et.properties +6 -0
  128. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_fi.properties +6 -0
  129. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_fr.properties +6 -0
  130. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_fr_CA.properties +6 -0
  131. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_hi.properties +6 -0
  132. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_hr.properties +6 -0
  133. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_hu.properties +6 -0
  134. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_id.properties +6 -0
  135. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_it.properties +6 -0
  136. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_iw.properties +6 -0
  137. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_ja.properties +6 -0
  138. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_kk.properties +6 -0
  139. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_ko.properties +6 -0
  140. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_lt.properties +6 -0
  141. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_lv.properties +6 -0
  142. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_mk.properties +6 -0
  143. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_ms.properties +6 -0
  144. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_nl.properties +6 -0
  145. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_no.properties +6 -0
  146. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_pl.properties +6 -0
  147. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_pt.properties +6 -0
  148. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_pt_PT.properties +6 -0
  149. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_ro.properties +6 -0
  150. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_ru.properties +6 -0
  151. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_sh.properties +6 -0
  152. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_sk.properties +6 -0
  153. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_sl.properties +6 -0
  154. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_sr.properties +6 -0
  155. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_sv.properties +6 -0
  156. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_th.properties +6 -0
  157. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_tr.properties +6 -0
  158. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_uk.properties +6 -0
  159. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_vi.properties +6 -0
  160. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_zh_CN.properties +6 -0
  161. package/src/main/js/sap/ushell/components/contentFinder/resources/resources_zh_TW.properties +6 -0
  162. package/src/main/js/sap/ushell/components/contentFinder/view/AppSearch.view.xml +174 -176
  163. package/src/main/js/sap/ushell/components/contentFinder/view/AppSearchCategoryTree.fragment.xml +28 -7
  164. package/src/main/js/sap/ushell/components/contentFinder/view/ContentFinderDialog.view.xml +1 -1
  165. package/src/main/js/sap/ushell/components/contentFinder/view/VisualizationsNoDataIllustratedMessage.fragment.xml +28 -0
  166. package/src/main/js/sap/ushell/components/contentFinderStandalone/Component.js +1 -1
  167. package/src/main/js/sap/ushell/components/contentFinderStandalone/controller/ContentFinderStandalone.controller.js +17 -14
  168. package/src/main/js/sap/ushell/components/contentFinderStandalone/manifest.json +1 -1
  169. package/src/main/js/sap/ushell/components/contentFinderStandalone/manifestAppSearch.json +1 -1
  170. package/src/main/js/sap/ushell/components/factsheet/Component.js +1 -1
  171. package/src/main/js/sap/ushell/components/homepage/ActionMode.js +1 -1
  172. package/src/main/js/sap/ushell/components/homepage/DashboardContent.view.js +1 -1
  173. package/src/main/js/sap/ushell/components/homepage/DashboardGroupsBox.js +1 -1
  174. package/src/main/js/sap/ushell/components/homepage/DashboardUIActions.js +1 -1
  175. package/src/main/js/sap/ushell/components/homepage/manifest.json +1 -1
  176. package/src/main/js/sap/ushell/components/pages/ActionMode.js +6 -1
  177. package/src/main/js/sap/ushell/components/pages/Component.js +1 -1
  178. package/src/main/js/sap/ushell/components/pages/MyHomeImport.js +1 -1
  179. package/src/main/js/sap/ushell/components/pages/controller/PageRuntime.controller.js +2 -2
  180. package/src/main/js/sap/ushell/components/pages/manifest.json +1 -1
  181. package/src/main/js/sap/ushell/components/runtimeSwitcher/controller/RuntimeSwitcher.controller.js +1 -1
  182. package/src/main/js/sap/ushell/components/runtimeSwitcher/manifest.json +1 -1
  183. package/src/main/js/sap/ushell/components/shell/FloatingContainer/Component.js +2 -1
  184. package/src/main/js/sap/ushell/components/shell/FloatingContainer/controls/FloatingContainer.js +74 -5
  185. package/src/main/js/sap/ushell/components/shell/FloatingContainer/manifest.json +1 -1
  186. package/src/main/js/sap/ushell/components/shell/MenuBar/manifest.json +1 -1
  187. package/src/main/js/sap/ushell/components/shell/NavigationBarMenu/controller/NavigationBarMenu.controller.js +1 -1
  188. package/src/main/js/sap/ushell/components/shell/NavigationBarMenu/manifest.json +1 -1
  189. package/src/main/js/sap/ushell/components/shell/Notifications/Component.js +1 -1
  190. package/src/main/js/sap/ushell/components/shell/ProductSwitch/Component.js +1 -1
  191. package/src/main/js/sap/ushell/components/shell/Search/manifest.json +1 -1
  192. package/src/main/js/sap/ushell/components/shell/SearchCEP/Component.js +1 -1
  193. package/src/main/js/sap/ushell/components/shell/SearchCEP/SearchCEP.controller.js +20 -4
  194. package/src/main/js/sap/ushell/components/shell/SearchCEP/SearchProviders/FrequentActivityProvider.js +1 -1
  195. package/src/main/js/sap/ushell/components/shell/SearchCEP/SearchProviders/RecentSearchProvider.js +1 -1
  196. package/src/main/js/sap/ushell/components/shell/SearchCEP/SearchProviders/SearchProvider.js +1 -1
  197. package/src/main/js/sap/ushell/components/shell/SearchCEP/SearchProviders/SearchServiceProvider.js +1 -1
  198. package/src/main/js/sap/ushell/components/shell/Settings/Component.js +1 -1
  199. package/src/main/js/sap/ushell/components/shell/Settings/appearance/Appearance.controller.js +149 -197
  200. package/src/main/js/sap/ushell/components/shell/Settings/appearance/Appearance.view.xml +88 -85
  201. package/src/main/js/sap/ushell/components/shell/Settings/appearance/AppearanceEntry.js +15 -19
  202. package/src/main/js/sap/ushell/components/shell/UserActionsMenu/Component.js +1 -1
  203. package/src/main/js/sap/ushell/components/shell/UserActionsMenu/UserActionsMenu.controller.js +2 -2
  204. package/src/main/js/sap/ushell/components/shell/UserImage/Component.js +1 -1
  205. package/src/main/js/sap/ushell/components/visualizationOrganizer/Component.js +1 -1
  206. package/src/main/js/sap/ushell/components/workPageBuilder/Component.js +30 -1
  207. package/src/main/js/sap/ushell/components/workPageBuilder/controller/WorkPageBuilder.accessibility.js +1 -1
  208. package/src/main/js/sap/ushell/components/workPageBuilder/controller/WorkPageBuilder.controller.js +30 -16
  209. package/src/main/js/sap/ushell/components/workPageBuilder/controls/WorkPage.js +1 -1
  210. package/src/main/js/sap/ushell/components/workPageBuilder/controls/WorkPageButton.js +1 -1
  211. package/src/main/js/sap/ushell/components/workPageBuilder/controls/WorkPageCell.js +1 -1
  212. package/src/main/js/sap/ushell/components/workPageBuilder/controls/WorkPageColumn.js +1 -1
  213. package/src/main/js/sap/ushell/components/workPageBuilder/controls/WorkPageColumnResizer.js +1 -1
  214. package/src/main/js/sap/ushell/components/workPageBuilder/controls/WorkPageRow.js +1 -1
  215. package/src/main/js/sap/ushell/components/workPageBuilder/manifest.json +1 -1
  216. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources.properties +29 -15
  217. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_ar.properties +3 -0
  218. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_bg.properties +3 -0
  219. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_ca.properties +3 -0
  220. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_cnr.properties +3 -0
  221. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_cs.properties +3 -0
  222. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_cy.properties +3 -0
  223. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_da.properties +3 -0
  224. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_de.properties +3 -0
  225. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_el.properties +3 -0
  226. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_en.properties +3 -0
  227. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_en_GB.properties +3 -0
  228. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_en_US_saprigi.properties +3 -0
  229. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_es.properties +3 -0
  230. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_es_MX.properties +3 -0
  231. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_et.properties +3 -0
  232. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_fi.properties +3 -0
  233. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_fr.properties +3 -0
  234. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_fr_CA.properties +3 -0
  235. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_hi.properties +3 -0
  236. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_hr.properties +3 -0
  237. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_hu.properties +3 -0
  238. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_id.properties +3 -0
  239. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_it.properties +3 -0
  240. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_iw.properties +4 -1
  241. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_ja.properties +3 -0
  242. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_kk.properties +3 -0
  243. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_ko.properties +3 -0
  244. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_lt.properties +3 -0
  245. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_lv.properties +3 -0
  246. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_mk.properties +3 -0
  247. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_ms.properties +3 -0
  248. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_nl.properties +3 -0
  249. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_no.properties +3 -0
  250. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_pl.properties +3 -0
  251. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_pt.properties +3 -0
  252. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_pt_PT.properties +3 -0
  253. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_ro.properties +3 -0
  254. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_ru.properties +3 -0
  255. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_sh.properties +3 -0
  256. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_sk.properties +3 -0
  257. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_sl.properties +3 -0
  258. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_sr.properties +3 -0
  259. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_sv.properties +3 -0
  260. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_th.properties +3 -0
  261. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_tr.properties +3 -0
  262. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_uk.properties +3 -0
  263. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_vi.properties +3 -0
  264. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_zh_CN.properties +3 -0
  265. package/src/main/js/sap/ushell/components/workPageBuilder/resources/resources_zh_TW.properties +3 -0
  266. package/src/main/js/sap/ushell/components/workPageRuntime/Component.js +1 -1
  267. package/src/main/js/sap/ushell/components/workPageRuntime/controller/WorkPageRuntime.controller.js +1 -1
  268. package/src/main/js/sap/ushell/components/workPageRuntime/manifest.json +1 -1
  269. package/src/main/js/sap/ushell/designtime/ApplicationContainer.designtime.js +1 -1
  270. package/src/main/js/sap/ushell/iconfonts.js +2 -1
  271. package/src/main/js/sap/ushell/library.js +1 -1
  272. package/src/main/js/sap/ushell/navigationMode.js +1 -1
  273. package/src/main/js/sap/ushell/performance/ShellAnalytics.js +18 -6
  274. package/src/main/js/sap/ushell/performance/StatisticalRecord.js +1 -1
  275. package/src/main/js/sap/ushell/plugins/appwarmup/Component.js +1 -1
  276. package/src/main/js/sap/ushell/renderer/Renderer.js +21 -20
  277. package/src/main/js/sap/ushell/renderer/Shell.controller.js +378 -576
  278. package/src/main/js/sap/ushell/renderer/Shell.view.js +5 -4
  279. package/src/main/js/sap/ushell/renderer/resources/resources.properties +57 -22
  280. package/src/main/js/sap/ushell/renderer/resources/resources_ar.properties +4 -4
  281. package/src/main/js/sap/ushell/renderer/resources/resources_bg.properties +4 -4
  282. package/src/main/js/sap/ushell/renderer/resources/resources_ca.properties +4 -4
  283. package/src/main/js/sap/ushell/renderer/resources/resources_cnr.properties +4 -4
  284. package/src/main/js/sap/ushell/renderer/resources/resources_cs.properties +4 -4
  285. package/src/main/js/sap/ushell/renderer/resources/resources_cy.properties +4 -4
  286. package/src/main/js/sap/ushell/renderer/resources/resources_da.properties +4 -4
  287. package/src/main/js/sap/ushell/renderer/resources/resources_de.properties +4 -4
  288. package/src/main/js/sap/ushell/renderer/resources/resources_el.properties +4 -4
  289. package/src/main/js/sap/ushell/renderer/resources/resources_en.properties +4 -4
  290. package/src/main/js/sap/ushell/renderer/resources/resources_en_GB.properties +4 -4
  291. package/src/main/js/sap/ushell/renderer/resources/resources_en_US_saprigi.properties +6 -4
  292. package/src/main/js/sap/ushell/renderer/resources/resources_es.properties +3 -3
  293. package/src/main/js/sap/ushell/renderer/resources/resources_es_MX.properties +4 -4
  294. package/src/main/js/sap/ushell/renderer/resources/resources_et.properties +4 -4
  295. package/src/main/js/sap/ushell/renderer/resources/resources_fi.properties +4 -4
  296. package/src/main/js/sap/ushell/renderer/resources/resources_fr.properties +4 -4
  297. package/src/main/js/sap/ushell/renderer/resources/resources_fr_CA.properties +10 -10
  298. package/src/main/js/sap/ushell/renderer/resources/resources_hi.properties +4 -4
  299. package/src/main/js/sap/ushell/renderer/resources/resources_hr.properties +4 -4
  300. package/src/main/js/sap/ushell/renderer/resources/resources_hu.properties +4 -4
  301. package/src/main/js/sap/ushell/renderer/resources/resources_id.properties +9 -9
  302. package/src/main/js/sap/ushell/renderer/resources/resources_it.properties +3 -3
  303. package/src/main/js/sap/ushell/renderer/resources/resources_iw.properties +4 -4
  304. package/src/main/js/sap/ushell/renderer/resources/resources_ja.properties +4 -4
  305. package/src/main/js/sap/ushell/renderer/resources/resources_kk.properties +4 -4
  306. package/src/main/js/sap/ushell/renderer/resources/resources_ko.properties +4 -4
  307. package/src/main/js/sap/ushell/renderer/resources/resources_lt.properties +4 -4
  308. package/src/main/js/sap/ushell/renderer/resources/resources_lv.properties +4 -4
  309. package/src/main/js/sap/ushell/renderer/resources/resources_mk.properties +4 -4
  310. package/src/main/js/sap/ushell/renderer/resources/resources_ms.properties +1 -1
  311. package/src/main/js/sap/ushell/renderer/resources/resources_nl.properties +4 -4
  312. package/src/main/js/sap/ushell/renderer/resources/resources_no.properties +4 -4
  313. package/src/main/js/sap/ushell/renderer/resources/resources_pl.properties +4 -4
  314. package/src/main/js/sap/ushell/renderer/resources/resources_pt.properties +4 -4
  315. package/src/main/js/sap/ushell/renderer/resources/resources_pt_PT.properties +4 -4
  316. package/src/main/js/sap/ushell/renderer/resources/resources_ro.properties +4 -4
  317. package/src/main/js/sap/ushell/renderer/resources/resources_ru.properties +4 -4
  318. package/src/main/js/sap/ushell/renderer/resources/resources_sh.properties +4 -4
  319. package/src/main/js/sap/ushell/renderer/resources/resources_sk.properties +4 -4
  320. package/src/main/js/sap/ushell/renderer/resources/resources_sl.properties +4 -4
  321. package/src/main/js/sap/ushell/renderer/resources/resources_sr.properties +4 -4
  322. package/src/main/js/sap/ushell/renderer/resources/resources_sv.properties +4 -4
  323. package/src/main/js/sap/ushell/renderer/resources/resources_th.properties +4 -4
  324. package/src/main/js/sap/ushell/renderer/resources/resources_tr.properties +4 -4
  325. package/src/main/js/sap/ushell/renderer/resources/resources_uk.properties +4 -4
  326. package/src/main/js/sap/ushell/renderer/resources/resources_vi.properties +4 -4
  327. package/src/main/js/sap/ushell/renderer/resources/resources_zh_CN.properties +4 -4
  328. package/src/main/js/sap/ushell/renderer/resources/resources_zh_TW.properties +4 -4
  329. package/src/main/js/sap/ushell/renderer/search/searchComponent/manifest.json +1 -1
  330. package/src/main/js/sap/ushell/renderers/fiori2/Shell.view.js +5 -4
  331. package/src/main/js/sap/ushell/services/AppLifeCycle.js +102 -107
  332. package/src/main/js/sap/ushell/services/AppState.js +1 -1
  333. package/src/main/js/sap/ushell/services/Bookmark.js +1 -1
  334. package/src/main/js/sap/ushell/services/BookmarkV2.js +1 -1
  335. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/Formatter.js +1 -1
  336. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/InboundIndex.js +1 -1
  337. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/InboundProvider.js +1 -1
  338. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/PrelaunchOperations.js +1 -1
  339. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/Search.js +1 -1
  340. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/StagedLogger.js +1 -1
  341. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/SystemContext.js +1 -1
  342. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/Utils.js +1 -1
  343. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/VirtualInbounds.js +1 -1
  344. package/src/main/js/sap/ushell/services/ClientSideTargetResolution/XAppStateProcessing.js +1 -1
  345. package/src/main/js/sap/ushell/services/ClientSideTargetResolution.js +2 -2
  346. package/src/main/js/sap/ushell/services/CommonDataModel/SiteConverter.js +1 -1
  347. package/src/main/js/sap/ushell/services/CommonDataModel/vizTypeDefaults/VizTypeDefaults.js +1 -1
  348. package/src/main/js/sap/ushell/services/CommonDataModel.js +1 -1
  349. package/src/main/js/sap/ushell/services/Configuration.js +1 -1
  350. package/src/main/js/sap/ushell/services/ConfigurationDefaults.js +1 -1
  351. package/src/main/js/sap/ushell/services/ContentExtensionAdapterFactory.js +1 -1
  352. package/src/main/js/sap/ushell/services/CrossApplicationNavigation.js +1 -1
  353. package/src/main/js/sap/ushell/services/DarkModeSupport.js +161 -144
  354. package/src/main/js/sap/ushell/services/Extension/Item.js +1 -1
  355. package/src/main/js/sap/ushell/services/Extension.js +3 -3
  356. package/src/main/js/sap/ushell/services/FlpLaunchPage.js +1 -1
  357. package/src/main/js/sap/ushell/services/FrameBoundExtension/FloatingContainer.js +1 -1
  358. package/src/main/js/sap/ushell/services/FrameBoundExtension/Footer.js +1 -1
  359. package/src/main/js/sap/ushell/services/FrameBoundExtension/Item.js +1 -1
  360. package/src/main/js/sap/ushell/services/FrameBoundExtension/SidePane.js +1 -1
  361. package/src/main/js/sap/ushell/services/FrameBoundExtension/ToolArea.js +1 -1
  362. package/src/main/js/sap/ushell/services/FrameBoundExtension.js +1 -1
  363. package/src/main/js/sap/ushell/services/LaunchPage.js +1 -1
  364. package/src/main/js/sap/ushell/services/Menu.js +1 -1
  365. package/src/main/js/sap/ushell/services/Message.js +1 -1
  366. package/src/main/js/sap/ushell/services/MessageBroker/MessageBrokerEngine.js +1 -1
  367. package/src/main/js/sap/ushell/services/MessageBroker.js +1 -1
  368. package/src/main/js/sap/ushell/services/MessageInternal.js +1 -1
  369. package/src/main/js/sap/ushell/services/Navigation/compatibility.js +1 -1
  370. package/src/main/js/sap/ushell/services/Navigation/utils.js +1 -1
  371. package/src/main/js/sap/ushell/services/Navigation.js +1 -1
  372. package/src/main/js/sap/ushell/services/NavigationDataProvider.js +1 -1
  373. package/src/main/js/sap/ushell/services/PageBuilding.js +1 -1
  374. package/src/main/js/sap/ushell/services/PagePersistence.js +1 -1
  375. package/src/main/js/sap/ushell/services/PageReferencing.js +1 -1
  376. package/src/main/js/sap/ushell/services/Pages.js +1 -1
  377. package/src/main/js/sap/ushell/services/Personalization.js +1 -1
  378. package/src/main/js/sap/ushell/services/PersonalizationV2.js +1 -1
  379. package/src/main/js/sap/ushell/services/PluginManager/Extensions.js +1 -1
  380. package/src/main/js/sap/ushell/services/PluginManager/HeaderExtensions.js +1 -1
  381. package/src/main/js/sap/ushell/services/PluginManager/MenuExtensions.js +1 -1
  382. package/src/main/js/sap/ushell/services/PluginManager.js +1 -1
  383. package/src/main/js/sap/ushell/services/ReferenceResolver.js +74 -100
  384. package/src/main/js/sap/ushell/services/Search.js +1 -1
  385. package/src/main/js/sap/ushell/services/SearchCEP.js +1 -1
  386. package/src/main/js/sap/ushell/services/SearchableContent.js +1 -1
  387. package/src/main/js/sap/ushell/services/ShellNavigation.js +1 -1
  388. package/src/main/js/sap/ushell/services/SmartNavigation.js +1 -1
  389. package/src/main/js/sap/ushell/services/SpaceContent.js +1 -1
  390. package/src/main/js/sap/ushell/services/UITracer.js +1 -1
  391. package/src/main/js/sap/ushell/services/URLShortening.js +1 -1
  392. package/src/main/js/sap/ushell/services/URLTemplate.js +1 -1
  393. package/src/main/js/sap/ushell/services/Ui5ComponentLoader/utils.js +2 -1
  394. package/src/main/js/sap/ushell/services/Ui5ComponentLoader.js +1 -1
  395. package/src/main/js/sap/ushell/services/UserDefaultParameterPersistence.js +1 -1
  396. package/src/main/js/sap/ushell/services/UserDefaultParameters.js +1 -1
  397. package/src/main/js/sap/ushell/services/UserInfo.js +1 -1
  398. package/src/main/js/sap/ushell/services/UserRecents.js +4 -4
  399. package/src/main/js/sap/ushell/services/VisualizationDataProvider.js +1 -1
  400. package/src/main/js/sap/ushell/services/VisualizationInstantiation.js +1 -1
  401. package/src/main/js/sap/ushell/services/_ContentExtensionAdapterFactory/ContentExtensionAdapterConfig.js +1 -1
  402. package/src/main/js/sap/ushell/services/_ContentExtensionAdapterFactory/FeaturedGroupConfig.js +1 -1
  403. package/src/main/js/sap/ushell/services/_CrossApplicationNavigation/utils.js +1 -1
  404. package/src/main/js/sap/ushell/services/_PageReferencing/PageReferencer.js +1 -1
  405. package/src/main/js/sap/ushell/state/ShellModel.js +31 -0
  406. package/src/main/js/sap/ushell/state/StateManager.js +28 -0
  407. package/src/main/js/sap/ushell/support/plugins/flpConfig/FlpConfigurationPlugin.js +1 -1
  408. package/src/main/js/sap/ushell/themes/base/fonts/BusinessSuiteInAppSymbols.ttf +0 -0
  409. package/src/main/js/sap/ushell/themes/base/fonts/BusinessSuiteInAppSymbols.woff +0 -0
  410. package/src/main/js/sap/ushell/themes/base/fonts/BusinessSuiteInAppSymbols.woff2 +0 -0
  411. package/src/main/js/sap/ushell/themes/base/library.source.less +0 -1
  412. package/src/main/js/sap/ushell/themes/sap_belize_base/library.source.less +0 -1
  413. package/src/main/js/sap/ushell/themes/sap_bluecrystal_base/library.source.less +0 -1
  414. package/src/main/js/sap/ushell/themes/sap_hcb/library.source.less +0 -1
  415. package/src/main/js/sap/ushell/ui/cards/RecentActivitiesExtension.js +1 -1
  416. package/src/main/js/sap/ushell/ui/footerbar/AboutButton.js +17 -21
  417. package/src/main/js/sap/ushell/ui/footerbar/AboutDialog.controller.js +358 -100
  418. package/src/main/js/sap/ushell/ui/footerbar/AboutDialog.fragment.xml +169 -90
  419. package/src/main/js/sap/ushell/ui/launchpad/ExtendedChangeDetection.js +1 -1
  420. package/src/main/js/sap/ushell/ui/launchpad/Page.js +77 -9
  421. package/src/main/js/sap/ushell/ui/launchpad/PageRenderer.js +20 -20
  422. package/src/main/js/sap/ushell/ui/launchpad/Section.js +1 -1
  423. package/src/main/js/sap/ushell/ui/launchpad/section/CompactArea.js +1 -1
  424. package/src/main/js/sap/ushell/ui/shell/ToolAreaItem.js +1 -1
  425. package/src/main/js/sap/ushell/ui/utils.js +1 -1
  426. package/src/main/js/sap/ushell/ui5service/ShellUIServiceFactory.js +1 -1
  427. package/src/main/js/sap/ushell/ui5service/UserStatus.js +1 -1
  428. package/src/main/js/sap/ushell/utils/DynamicTileRequest.js +1 -3
  429. package/src/main/js/sap/ushell/utils/RestrictedJSONModel.js +3 -1
  430. package/src/main/js/sap/ushell/utils/UrlParsing.js +38 -0
  431. package/src/main/js/sap/ushell/utils/UrlShortening.js +1 -1
  432. package/src/main/js/sap/ushell/utils/workpage/DestinationResolver.js +13 -1
  433. package/src/main/js/sap/ushell/utils/workpage/WorkPageHost.js +1 -1
  434. package/src/main/js/sap/ushell/utils/workpage/WorkPageService.js +1 -1
  435. package/src/main/js/sap/ushell/utils/workpage/WorkPageVizInstantiation.js +1 -1
  436. package/src/main/js/sap/ushell/utils/workpage/resources/resources.properties +43 -27
  437. package/src/main/js/sap/ushell/utils/workpage/resources/resources_ar.properties +2 -2
  438. package/src/main/js/sap/ushell/utils/workpage/resources/resources_bg.properties +2 -2
  439. package/src/main/js/sap/ushell/utils/workpage/resources/resources_ca.properties +2 -2
  440. package/src/main/js/sap/ushell/utils/workpage/resources/resources_cnr.properties +2 -2
  441. package/src/main/js/sap/ushell/utils/workpage/resources/resources_cs.properties +2 -2
  442. package/src/main/js/sap/ushell/utils/workpage/resources/resources_cy.properties +2 -2
  443. package/src/main/js/sap/ushell/utils/workpage/resources/resources_da.properties +2 -2
  444. package/src/main/js/sap/ushell/utils/workpage/resources/resources_de.properties +2 -2
  445. package/src/main/js/sap/ushell/utils/workpage/resources/resources_el.properties +2 -2
  446. package/src/main/js/sap/ushell/utils/workpage/resources/resources_en.properties +2 -2
  447. package/src/main/js/sap/ushell/utils/workpage/resources/resources_en_GB.properties +2 -2
  448. package/src/main/js/sap/ushell/utils/workpage/resources/resources_es.properties +2 -2
  449. package/src/main/js/sap/ushell/utils/workpage/resources/resources_es_MX.properties +2 -2
  450. package/src/main/js/sap/ushell/utils/workpage/resources/resources_et.properties +2 -2
  451. package/src/main/js/sap/ushell/utils/workpage/resources/resources_fi.properties +2 -2
  452. package/src/main/js/sap/ushell/utils/workpage/resources/resources_fr.properties +2 -2
  453. package/src/main/js/sap/ushell/utils/workpage/resources/resources_fr_CA.properties +2 -2
  454. package/src/main/js/sap/ushell/utils/workpage/resources/resources_hi.properties +2 -2
  455. package/src/main/js/sap/ushell/utils/workpage/resources/resources_hr.properties +2 -2
  456. package/src/main/js/sap/ushell/utils/workpage/resources/resources_hu.properties +5 -5
  457. package/src/main/js/sap/ushell/utils/workpage/resources/resources_id.properties +2 -2
  458. package/src/main/js/sap/ushell/utils/workpage/resources/resources_it.properties +2 -2
  459. package/src/main/js/sap/ushell/utils/workpage/resources/resources_iw.properties +2 -2
  460. package/src/main/js/sap/ushell/utils/workpage/resources/resources_ja.properties +2 -2
  461. package/src/main/js/sap/ushell/utils/workpage/resources/resources_kk.properties +2 -2
  462. package/src/main/js/sap/ushell/utils/workpage/resources/resources_ko.properties +2 -2
  463. package/src/main/js/sap/ushell/utils/workpage/resources/resources_lt.properties +2 -2
  464. package/src/main/js/sap/ushell/utils/workpage/resources/resources_lv.properties +2 -2
  465. package/src/main/js/sap/ushell/utils/workpage/resources/resources_mk.properties +2 -2
  466. package/src/main/js/sap/ushell/utils/workpage/resources/resources_ms.properties +2 -2
  467. package/src/main/js/sap/ushell/utils/workpage/resources/resources_nl.properties +2 -2
  468. package/src/main/js/sap/ushell/utils/workpage/resources/resources_no.properties +2 -2
  469. package/src/main/js/sap/ushell/utils/workpage/resources/resources_pl.properties +2 -2
  470. package/src/main/js/sap/ushell/utils/workpage/resources/resources_pt.properties +2 -2
  471. package/src/main/js/sap/ushell/utils/workpage/resources/resources_pt_PT.properties +2 -2
  472. package/src/main/js/sap/ushell/utils/workpage/resources/resources_ro.properties +2 -2
  473. package/src/main/js/sap/ushell/utils/workpage/resources/resources_ru.properties +2 -2
  474. package/src/main/js/sap/ushell/utils/workpage/resources/resources_sh.properties +2 -2
  475. package/src/main/js/sap/ushell/utils/workpage/resources/resources_sk.properties +2 -2
  476. package/src/main/js/sap/ushell/utils/workpage/resources/resources_sl.properties +2 -2
  477. package/src/main/js/sap/ushell/utils/workpage/resources/resources_sr.properties +2 -2
  478. package/src/main/js/sap/ushell/utils/workpage/resources/resources_sv.properties +2 -2
  479. package/src/main/js/sap/ushell/utils/workpage/resources/resources_th.properties +2 -2
  480. package/src/main/js/sap/ushell/utils/workpage/resources/resources_tr.properties +2 -2
  481. package/src/main/js/sap/ushell/utils/workpage/resources/resources_uk.properties +3 -3
  482. package/src/main/js/sap/ushell/utils/workpage/resources/resources_vi.properties +2 -2
  483. package/src/main/js/sap/ushell/utils/workpage/resources/resources_zh_CN.properties +2 -2
  484. package/src/main/js/sap/ushell/utils/workpage/resources/resources_zh_TW.properties +2 -2
  485. package/src/main/js/sap/ushell/utils.js +8 -20
  486. package/src/test/js/sap/ushell/bootstrap/sandbox.js +1 -1
  487. package/src/main/js/sap/ushell/themes/base/AppearanceView.less +0 -213
  488. package/src/main/js/sap/ushell/themes/sap_belize_base/AppearanceView.less +0 -213
  489. package/src/main/js/sap/ushell/themes/sap_bluecrystal_base/AppearanceView.less +0 -213
  490. package/src/main/js/sap/ushell/themes/sap_hcb/base_AppearanceView.less +0 -213
@@ -2,9 +2,10 @@
2
2
 
3
3
  /**
4
4
  * @fileOverview handle all the resources for the different applications.
5
- * @version 1.129.1
5
+ * @version 1.130.1
6
6
  */
7
7
  sap.ui.define([
8
+ "sap/ui/Device",
8
9
  "sap/ui/core/Element",
9
10
  "sap/ui/core/EventBus",
10
11
  "sap/ushell/components/applicationIntegration/Storage",
@@ -27,12 +28,17 @@ sap.ui.define([
27
28
  "sap/ushell/services/MessageBroker/MessageBrokerEngine",
28
29
  "sap/ushell/renderer/utils",
29
30
  "sap/m/library",
31
+ "sap/ushell/AppInfoParameters",
30
32
  "sap/ushell/Container",
33
+ "sap/ushell/resources",
34
+ "sap/ushell/state/ShellModel",
31
35
  "sap/ushell/state/StateManager",
32
36
  "sap/ushell/state/KeepAlive",
33
37
  "sap/ushell/ui5service/ShellUIServiceFactory",
34
- "sap/ui/core/service/ServiceFactoryRegistry"
38
+ "sap/ui/core/service/ServiceFactoryRegistry",
39
+ "sap/base/util/ObjectPath"
35
40
  ], (
41
+ Device,
36
42
  Element,
37
43
  EventBus,
38
44
  Storage,
@@ -50,30 +56,42 @@ sap.ui.define([
50
56
  UriParameters,
51
57
  Log,
52
58
  EventHub,
53
- oUrlParsing,
59
+ UrlParsing,
54
60
  hasher,
55
61
  MessageBrokerEngine,
56
62
  RendererUtils,
57
63
  mobileLibrary,
64
+ AppInfoParameters,
58
65
  Container,
66
+ ushellResources,
67
+ ShellModel,
59
68
  StateManager,
60
69
  KeepAlive,
61
70
  ShellUIServiceFactory,
62
- ServiceFactoryRegistry
71
+ ServiceFactoryRegistry,
72
+ ObjectPath
63
73
  ) => {
64
74
  "use strict";
65
75
 
66
76
  // shortcut for sap.ushell.state.StateManager.ShellMode
67
77
  const ShellMode = StateManager.ShellMode;
68
78
 
79
+ // shortcut for sap.ushell.state.StateManager.LaunchpadState
80
+ const LaunchpadState = StateManager.LaunchpadState;
81
+
82
+ // shortcut for sap.ushell.state.StateManager.Operation
83
+ const Operation = StateManager.Operation;
84
+
69
85
  // shortcut for sap.m.URLHelper
70
86
  const URLHelper = mobileLibrary.URLHelper;
71
87
 
72
- const CACHED_APP_TYPES = ["URL"];
88
+ // todo: [FLPCOREANDUX-10024] cleanup
89
+ // const CACHED_APP_TYPES = ["URL"];
73
90
 
74
91
  const KEEP_ALIVE_MODES = {
75
92
  FULL: "true",
76
- RESTRICTED: "restricted"
93
+ RESTRICTED: "restricted",
94
+ FALSE: "false"
77
95
  };
78
96
 
79
97
  function AppLifeCycle () {
@@ -81,12 +99,8 @@ sap.ui.define([
81
99
  let bDisableHomeAppCache = false;
82
100
  let bEnableRouterRetrigger = true;
83
101
  let oCurrentApplication = {};
84
- const oGlobalShellCommunicationHandlers = [];
85
- const oGlobalIframeCommunicationHandlers = {};
86
102
  const oComponentCreatedPromises = {};
87
- let isBackNavigationChanged = false;
88
- let sRootIntent,
89
- oGlobalShellUIService,
103
+ let oGlobalShellUIService,
90
104
  fnOldTriggerEmail,
91
105
  oViewPortContainer;
92
106
 
@@ -102,112 +116,67 @@ sap.ui.define([
102
116
  return RelatedServices;
103
117
  };
104
118
 
105
- ///////////////////APPLICATION INTEGRATION API///////////////////////////////
106
- ///////////////////END APPLICATION INTEGRATION API///////////////////////////////
107
-
108
- /**
109
- * @param {string} sAppId
110
- * @returns {boolean} Returns true if it is the current application
111
- */
112
- this.isCurrentApp = function (sAppId) {
113
- return (oCurrentApplication.appId === sAppId);
114
- };
115
-
116
119
  /**
117
120
  * Sets the componentCreated promise for a given appId if it does not exist yet.
118
121
  * Returns the promise along with the resolve and reject functions.
119
122
  * @private
120
123
  * @since 1.125.0
121
- * @param {string} sAppId The id of the created application.
124
+ * @param {string} sStorageAppId The id of the created application.
122
125
  * @returns {{
123
126
  * promise: Promise,
124
127
  * resolve: function,
125
128
  * reject: function
126
129
  * }} An object containing the promise and the resolve and reject functions.
127
130
  */
128
- this.setComponentCreatedPromise = function (sAppId) {
129
- if (!oComponentCreatedPromises[sAppId]) {
130
- oComponentCreatedPromises[sAppId] = {};
131
- oComponentCreatedPromises[sAppId].promise = new Promise((resolve, reject) => {
132
- oComponentCreatedPromises[sAppId].resolve = resolve;
133
- oComponentCreatedPromises[sAppId].reject = reject;
131
+ this._setComponentCreatedPromise = function (sStorageAppId) {
132
+ if (!oComponentCreatedPromises[sStorageAppId]) {
133
+ oComponentCreatedPromises[sStorageAppId] = {};
134
+ oComponentCreatedPromises[sStorageAppId].promise = new Promise((resolve, reject) => {
135
+ oComponentCreatedPromises[sStorageAppId].resolve = resolve;
136
+ oComponentCreatedPromises[sStorageAppId].reject = reject;
134
137
  });
135
138
  }
136
139
 
137
- return oComponentCreatedPromises[sAppId];
140
+ return oComponentCreatedPromises[sStorageAppId];
138
141
  };
139
142
 
140
143
  /**
141
144
  * Resolves the componentCreated promise for the given appId. If the promise does not yet exist, it is created.
142
- * @param {string} sAppId The id of the created application.
143
- * @private
144
- * @since 1.125.0
145
- */
146
- this.resolveComponentCreatedPromise = function (sAppId) {
147
- if (!sAppId) { return; }
148
- this.setComponentCreatedPromise(sAppId).resolve();
149
- };
150
-
151
- /**
152
- * Rejects the componentCreated promise for the given appId. If the promise does not yet exist, it is created.
153
- * @param {string} sAppId The id of the created application.
145
+ * @param {string} sStorageAppId The id of the created application.
154
146
  * @private
155
147
  * @since 1.125.0
156
148
  */
157
- this.rejectComponentCreatedPromise = function (sAppId) {
158
- if (!sAppId) { return; }
159
- this.setComponentCreatedPromise(sAppId).reject(`Component was not created for app "${sAppId}"`);
149
+ this._resolveComponentCreatedPromise = function (sStorageAppId) {
150
+ if (!sStorageAppId) {
151
+ return;
152
+ }
153
+ this._setComponentCreatedPromise(sStorageAppId).resolve();
160
154
  };
161
155
 
162
156
  /**
163
157
  * Returns the componentCreated promise for the given appId. If the promise does not yet exist, it is created.
164
- * @param {string} sAppId The id of the created application.
158
+ * @param {string} sStorageAppId The id of the created application.
165
159
  * @returns {Promise | undefined} The componentCreated promise for the given appId or undefined if no appId is given.
166
160
  * @private
167
161
  * @since 1.125.0
168
162
  */
169
- this.getComponentCreatedPromise = function (sAppId) {
170
- if (!sAppId) { return; }
171
- return this.setComponentCreatedPromise(sAppId).promise;
172
- };
173
-
174
- /**
175
- * @param {string} sAppId
176
- * @param {string} sFixedShellHash
177
- * @returns {boolean} Returns true if a similar app was found in the cache
178
- */
179
- this.isAppWithSimilarShellHashInCache = function (sAppId, sFixedShellHash) {
180
- const oAppEntry = Storage.get(sAppId);
181
-
182
- if (oAppEntry) {
183
- if (oAppEntry.shellHash === sFixedShellHash) {
184
- return true;
185
- }
186
- return false;
187
- }
188
- return false;
189
- };
190
-
191
- /**
192
- * @param {string} sAppId
193
- * @returns {boolean} Returns true if the app is in the cache
194
- */
195
- this.isAppInCache = function (sAppId) {
196
- return !!Storage.get(sAppId);
163
+ this._getComponentCreatedPromise = function (sStorageAppId) {
164
+ if (!sStorageAppId) { return; }
165
+ return this._setComponentCreatedPromise(sStorageAppId).promise;
197
166
  };
198
167
 
199
168
  /**
200
- * @param {string} sAppId
169
+ * @param {string} sId Id of the control might end with "-component"
201
170
  * @returns {string} Returns the normalized appId
202
171
  */
203
- this.normalizeAppId = function (sAppId) {
172
+ this._normalizeAppId = function (sId) {
204
173
  const sCmp = "-component";
205
- const isCmp = sAppId.endsWith(sCmp);
174
+ const isCmp = sId.endsWith(sCmp);
206
175
 
207
176
  if (isCmp) {
208
- return sAppId.substring(0, sAppId.length - sCmp.length);
177
+ return sId.substring(0, sId.length - sCmp.length);
209
178
  }
210
- return sAppId;
179
+ return sId;
211
180
  };
212
181
 
213
182
  /**
@@ -215,13 +184,15 @@ sap.ui.define([
215
184
  * @param {string} sChannel
216
185
  * @param {object} oData
217
186
  */
218
- this.onComponentCreated = function (oEvent, sChannel, oData) {
187
+ this._onComponentCreated = function (oEvent, sChannel, oData) {
219
188
  const oApp = oData.component;
220
- const sAppId = this.normalizeAppId(oApp.getId());
189
+ const sStorageAppId = this._normalizeAppId(oApp.getId());
190
+ const oStorageEntry = Storage.get(sStorageAppId);
191
+
192
+ if (oStorageEntry) {
193
+ oStorageEntry.app = oApp;
194
+ Application.active(oStorageEntry.app);
221
195
 
222
- if (this.isAppInCache(sAppId)) {
223
- Storage.get(sAppId).app = oApp;
224
- this.active(sAppId);
225
196
  } else {
226
197
  oCurrentApplication.app = oApp;
227
198
 
@@ -230,7 +201,7 @@ sap.ui.define([
230
201
  }
231
202
  }
232
203
 
233
- this.resolveComponentCreatedPromise(sAppId);
204
+ this._resolveComponentCreatedPromise(sStorageAppId);
234
205
  };
235
206
 
236
207
  /**
@@ -238,15 +209,15 @@ sap.ui.define([
238
209
  * @param {string} sChannel
239
210
  * @param {object} oData
240
211
  */
241
- this.onGetMe = function (oEvent, sChannel, oData) {
212
+ this._onGetMe = function (oEvent, sChannel, oData) {
242
213
  oData.AppLifeCycle = this;
243
214
  };
244
215
 
245
216
  /**
246
- * @param {string} sAppId
217
+ * @param {string} sStorageAppId
247
218
  */
248
- this.store = function (sAppId) {
249
- const oStorageEntry = Storage.get(sAppId);
219
+ this._store = function (sStorageAppId) {
220
+ const oStorageEntry = Storage.get(sStorageAppId);
250
221
 
251
222
  if (oStorageEntry) {
252
223
  Application.store(oStorageEntry);
@@ -255,47 +226,39 @@ sap.ui.define([
255
226
  };
256
227
 
257
228
  /**
258
- * @param {string} sAppId
259
- * @param {object} oFrom
229
+ * @param {string} sStorageAppId
230
+ * @param {object} oApplicationContainer
260
231
  * @param {boolean} bHardDestroy
261
232
  * @returns {Promise} Resolves when the app is destroyed.
262
233
  */
263
- this.destroyApplication = async function (sAppId, oFrom, bHardDestroy) {
264
- const oStorageEntry = Storage.get(sAppId);
265
-
266
- if (!sAppId || !oFrom) {
267
- return;
268
- }
234
+ this._destroyApplication = async function (sStorageAppId, oApplicationContainer, bHardDestroy) {
235
+ const oStorageEntry = Storage.get(sStorageAppId);
269
236
 
270
- function doDestroy () {
271
- BlueBoxHandler.deleteBlueBoxByContainer(oFrom);
272
- Application.destroy(oFrom);
273
- AppMeta.destroy(oFrom);
274
- KeepAlive.destroy(oStorageEntry);
275
- }
276
-
277
- if (bHardDestroy) {
278
- Storage.removeByContainer(oFrom);
279
- this.removeControl(sAppId);
280
- doDestroy();
237
+ if (!sStorageAppId || !oApplicationContainer) {
281
238
  return;
282
239
  }
283
240
 
284
- if (oStorageEntry) {
285
- Storage.removeById(sAppId);
241
+ // ignore stateful destroy when hard destroy is requested
242
+ if (oStorageEntry && !bHardDestroy) {
243
+ Storage.removeById(sStorageAppId);
286
244
  if (BlueBoxHandler.isStatefulContainer(oStorageEntry.container)) {
287
- await BlueBoxHandler.statefulDestroyApp(oStorageEntry.container, sAppId);
245
+ await BlueBoxHandler.statefulDestroyApp(oStorageEntry.container, sStorageAppId);
288
246
  } else if (!BlueBoxHandler.returnUnusedKeepAliveContainer(oStorageEntry.container)) {
289
- this.removeControl(sAppId);
247
+ this._removeApplicationContainerFromViewPort(sStorageAppId);
290
248
  BlueBoxHandler.deleteBlueBoxByContainer(oStorageEntry.container);
291
249
  oStorageEntry.container.destroy();
292
250
  } else {
293
- await this.handleExitStateful(sAppId, oStorageEntry.container, false);
251
+ await this._handleExitStateful(oStorageEntry.container, false);
294
252
  }
295
253
  return;
296
254
  }
297
255
 
298
- this.removeControl(sAppId);
256
+
257
+ if (bHardDestroy) {
258
+ Storage.removeByContainer(oApplicationContainer);
259
+ }
260
+
261
+ this._removeApplicationContainerFromViewPort(sStorageAppId);
299
262
  /**
300
263
  * If the application running in an iframe registered for "before close" event,
301
264
  * we first post it a message to prepare for closing (usually, the app will close
@@ -309,10 +272,9 @@ sap.ui.define([
309
272
  * This mechanism was added to solve the change made in Chrome to disallow Sync XHR on
310
273
  * browser close.
311
274
  */
312
- const oPromise = oFrom?.sendBeforeAppCloseEvent?.() || Promise.resolve();
313
-
314
275
  try {
315
- await ushellUtils.promisify(oPromise);
276
+ const oThenable = oApplicationContainer.sendBeforeAppCloseEvent();
277
+ await ushellUtils.promisify(oThenable);
316
278
  } catch (sError) {
317
279
  Log.error(
318
280
  "FLP got a failed response from the iframe for the 'sap.ushell.services.CrossApplicationNavigation.beforeAppCloseEvent' message sent",
@@ -320,19 +282,22 @@ sap.ui.define([
320
282
  "sap.ushell.components.applicationIntegration.AppLifeCycle.js"
321
283
  );
322
284
  }
323
- doDestroy();
285
+
286
+ BlueBoxHandler.deleteBlueBoxByContainer(oApplicationContainer);
287
+ Application.destroy(oApplicationContainer);
288
+ AppMeta.destroy(oApplicationContainer);
289
+ KeepAlive.destroy(oStorageEntry);
324
290
  };
325
291
 
326
292
  /**
327
- * @param {string} sAppId
293
+ * @param {string} sStorageAppId
328
294
  */
329
- this.restore = function (sAppId) {
330
- const oStorageEntry = Storage.get(sAppId);
295
+ this._restore = function (sStorageAppId) {
296
+ const oStorageEntry = Storage.get(sStorageAppId);
331
297
 
332
298
  if (oStorageEntry?.stateStored) {
333
299
  // 1) Extensions
334
300
  RelatedServices.restore(oStorageEntry.service);
335
- this.setBackNavigationChanged(true);
336
301
  AppMeta.restore(oStorageEntry.meta);
337
302
  // 2) Extension API
338
303
  ShellUIServiceFactory.restore(oStorageEntry);
@@ -342,150 +307,123 @@ sap.ui.define([
342
307
  };
343
308
 
344
309
  /**
345
- * @param {string} sAppId
346
- */
347
- this.active = function (sAppId) {
348
- const oStorageEntry = Storage.get(sAppId);
349
-
350
- if (oStorageEntry) {
351
- Application.active(oStorageEntry.app);
352
- }
353
- };
354
-
355
- /**
356
- * @param {string} sFromId
357
- * @param {object} oFrom
358
- * @param {boolean} bIsHomePage
359
- * @param {boolean} bForceCloseApp
310
+ * @param {object} oApplicationContainer
311
+ * @param {boolean} bNavigationToFlpComponent
312
+ * @param {boolean} [bForceCloseApp]
360
313
  * @returns {Promise} Resolves when the app is closed.
361
314
  */
362
- this.handleExitStateful = function (sFromId, oFrom, bIsHomePage, bForceCloseApp) {
363
- const sActualAppFromId = oFrom.getCurrentAppId?.();
315
+ this._handleExitStateful = function (oApplicationContainer, bNavigationToFlpComponent, bForceCloseApp) {
316
+ const sActualAppFromId = oApplicationContainer.getCurrentAppId();
364
317
 
365
318
  if (Storage.get(sActualAppFromId)) {
366
- if ((RelatedServices.isBackNavigation() && !bIsHomePage) || (bForceCloseApp)) {
367
- EventBus.getInstance().publish("sap.ushell", "appClosed", oFrom);
319
+ if ((RelatedServices.isBackNavigation() && !bNavigationToFlpComponent) || (bForceCloseApp)) {
320
+ EventBus.getInstance().publish("sap.ushell", "appClosed", oApplicationContainer);
368
321
  Storage.removeById(sActualAppFromId);
369
- return BlueBoxHandler.statefulDestroyApp(oFrom);
322
+ return BlueBoxHandler.statefulDestroyApp(oApplicationContainer);
370
323
  }
371
324
  // in this case the store of the currently running application, so we do not need to pass the sCacheId
372
- EventBus.getInstance().publish("sap.ushell", "appClosed", oFrom);
373
- return BlueBoxHandler.statefulStoreKeepAliveApp(oFrom, sActualAppFromId);
325
+ EventBus.getInstance().publish("sap.ushell", "appClosed", oApplicationContainer);
326
+ return BlueBoxHandler.statefulStoreKeepAliveApp(oApplicationContainer, sActualAppFromId);
374
327
  }
375
328
  // in this case the destroy of the currently running application, so we do not need to pass the sCacheId
376
- return BlueBoxHandler.statefulDestroyApp(oFrom);
329
+ return BlueBoxHandler.statefulDestroyApp(oApplicationContainer);
377
330
  };
378
331
 
379
332
  /**
380
- * @param {string} sFromId
381
- * @param {object} oFrom
382
- * @param {string} sToId
383
- * @param {object} oTo
384
- * @param {boolean} bIsHomePage
333
+ * @param {object} oOldApplicationContainer
334
+ * @param {boolean} bNavigationToFlpComponent
385
335
  * @param {boolean} bFromAfterNavigate
386
336
  * @returns {Promise} Resolves when the app is closed.
387
337
  */
388
- this.handleExitApplication = async function (sFromId, oFrom, sToId, oTo, bIsHomePage, bFromAfterNavigate) {
389
- function fnCloseKeepAliveIfRestricted (oApp) {
390
- return (oApp.keepAliveMode === KEEP_ALIVE_MODES.RESTRICTED);
338
+ this._handleExitApplication = async function (oOldApplicationContainer, bNavigationToFlpComponent, bFromAfterNavigate) {
339
+ if (!oOldApplicationContainer) {
340
+ return;
391
341
  }
392
342
 
393
- //this code must be at the beginning of the function to allow it to be processed once in
394
- //a cycle of opening an app
395
- if (sToId && oTo?.getIframeReusedForApp?.()) {
396
- oTo.setProperty("iframeReusedForApp", false, true);
397
- PostMessageUtils.postMessageToIframeApp(oTo, "sap.ushell.sessionHandler", "afterApplicationShow", {}, false);
398
- }
343
+ const sOldStorageAppId = oOldApplicationContainer.getCurrentAppId();
399
344
 
400
- //if called from onAfterNavigate, do nothing if oFrom is stateful container, because
401
- //application was already closed at the beginning of 'handleControl'
402
- if (!bIsHomePage && bFromAfterNavigate && (BlueBoxHandler.isStatefulContainer(oFrom) || BlueBoxHandler.isStatefulContainerInKeepAlivePool(oFrom))) {
345
+ if (!sOldStorageAppId) {
403
346
  return;
404
347
  }
405
348
 
406
- if (oFrom?.getCurrentAppId?.()) {
407
- sFromId = oFrom.getCurrentAppId();
349
+ // todo: [FLPCOREANDUX-10024] should not be necessary; the destroy should be callable multiple times w/o issues
350
+ // if called from onAfterNavigate, do nothing if oOldApplicationContainer is stateful container, because
351
+ // application was already closed at the beginning of 'handleCreateApplicationContainer'
352
+ if (!bNavigationToFlpComponent
353
+ && bFromAfterNavigate
354
+ && (
355
+ BlueBoxHandler.isStatefulContainer(oOldApplicationContainer)
356
+ || BlueBoxHandler.isStatefulContainerInKeepAlivePool(oOldApplicationContainer)
357
+ )
358
+ ) {
359
+ return;
408
360
  }
409
361
 
410
- if (sFromId && oFrom) {
411
- // STATEFUL
412
- if (BlueBoxHandler.isStatefulContainer(oFrom)) {
413
- await this.handleExitStateful(sFromId, oFrom, bIsHomePage);
362
+ // STATEFUL
363
+ if (BlueBoxHandler.isStatefulContainer(oOldApplicationContainer)) {
364
+ await this._handleExitStateful(oOldApplicationContainer, bNavigationToFlpComponent);
414
365
 
415
- //STATELESS
416
- } else if (Storage.get(sFromId)) {
417
- // Back Navigation Case
418
- if (RelatedServices.isBackNavigation() && !bIsHomePage) {
419
- //check if the Iframe needs to be cached instead of destroy
420
- if (!BlueBoxHandler.returnUnusedKeepAliveContainer(oFrom)) {
421
- await this.destroyApplication(sFromId, oFrom);
422
- } else {
423
- await this.handleExitStateful(sFromId, oFrom, bIsHomePage);
424
- }
425
-
426
- // Forward Navigation Cases
427
- } else if (oFrom.getApplicationType() === "UI5") {
428
- // Wait until navigation's source app has been started completely, so that a later back navigation finds a proper app that
429
- // can be re-enabled (keep-alive scenario)
430
- await this.getComponentCreatedPromise(sFromId);
431
- this.store(sFromId);
366
+ //STATELESS
367
+ } else if (Storage.get(sOldStorageAppId)) {
368
+ // Back Navigation Case
369
+ if (RelatedServices.isBackNavigation() && !bNavigationToFlpComponent) {
370
+ //check if the Iframe needs to be cached instead of destroy
371
+ if (!BlueBoxHandler.returnUnusedKeepAliveContainer(oOldApplicationContainer)) {
372
+ await this._destroyApplication(sOldStorageAppId, oOldApplicationContainer);
432
373
  } else {
433
- this.store(sFromId);
434
- }
435
- EventBus.getInstance().publish("sap.ushell", "appClosed", oFrom);
436
-
437
- // LEGACY STATEFUL (WebGUI)
438
- } else if (oFrom.getStatefulType?.() === BlueBoxHandler.STATEFUL_TYPES.GUI_V1) {
439
- if (bIsHomePage) {
440
- await PostMessageUtils.postMessageToIframeApp(oFrom, "sap.gui", "triggerCloseSessionImmediately");
374
+ await this._handleExitStateful(oOldApplicationContainer, bNavigationToFlpComponent);
441
375
  }
442
376
 
443
- // THE REST...
377
+ // Forward Navigation Cases
378
+ } else if (oOldApplicationContainer.getApplicationType() === "UI5") {
379
+ // Wait until navigation's source app has been started completely, so that a later back navigation finds a proper app that
380
+ // can be re-enabled (keep-alive scenario)
381
+ await this._getComponentCreatedPromise(sOldStorageAppId);
382
+ this._store(sOldStorageAppId);
444
383
  } else {
445
- const bIsAppOfTypeCachable = CACHED_APP_TYPES.indexOf(oFrom.getApplicationType) >= 0;
446
-
447
- //destroy the application and its resources
448
- const bIsKeepAlive = this.isAppOfTypeCached(sFromId, bIsAppOfTypeCachable);
449
- if (!bIsKeepAlive) {
450
- await this.destroyApplication(sFromId, oFrom);
451
- }
384
+ this._store(sOldStorageAppId);
452
385
  }
386
+ EventBus.getInstance().publish("sap.ushell", "appClosed", oOldApplicationContainer);
453
387
 
454
- if (bIsHomePage) {
455
- // todo: [FLPCOREANDUX-10024] Check whether we need to await the close as well
456
- this.closeKeepAliveApps(fnCloseKeepAliveIfRestricted);
388
+ // LEGACY STATEFUL (WebGUI)
389
+ } else if (oOldApplicationContainer.getStatefulType() === BlueBoxHandler.STATEFUL_TYPES.GUI_V1) {
390
+ if (bNavigationToFlpComponent) {
391
+ await PostMessageUtils.postMessageToIframeApp(oOldApplicationContainer, "sap.gui", "triggerCloseSessionImmediately");
457
392
  }
458
393
 
459
- //handle the case of appFiner
460
- if (sFromId.indexOf("Shell-appfinder-component") > 0) {
461
- EventBus.getInstance().publish("sap.ushell", "appFinderAfterNavigate");
394
+ // THE REST...
395
+ } else {
396
+ //destroy the application and its resources
397
+ const sKeepAliveMode = this._calculateKeepAliveMode(sOldStorageAppId, {}, {});
398
+ const bShouldBeCached = !!sKeepAliveMode;
399
+ if (!bShouldBeCached) {
400
+ await this._destroyApplication(sOldStorageAppId, oOldApplicationContainer);
462
401
  }
463
402
  }
464
-
465
- EventBus.getInstance().publish("relatedServices", "resetBackNavigation");
466
403
  };
467
404
 
468
405
  /**
469
406
  * @param {function(): boolean} fnFilterApps The filter function
470
407
  * @returns {Promise} Resolves when all keep alive apps are closed.
471
408
  */
472
- this.closeKeepAliveApps = function (fnFilterApps) {
409
+ this._closeKeepAliveApps = function (fnFilterApps) {
473
410
  try {
474
411
  const aKeepAliveRestrictedApps = [];
475
412
 
476
- Storage.forEach((oApp) => {
477
- if (fnFilterApps(oApp)) {
478
- aKeepAliveRestrictedApps.push(oApp);
413
+ Storage.forEach((oStorageEntry) => {
414
+ if (fnFilterApps(oStorageEntry)) {
415
+ aKeepAliveRestrictedApps.push(oStorageEntry);
479
416
  }
480
417
  });
481
418
  const aClosePromises = aKeepAliveRestrictedApps.map((oRestrictedApp) => {
482
419
  //check if it needs to be cached instead of destroy
483
420
  const bDestroy = !BlueBoxHandler.returnUnusedKeepAliveContainer(oRestrictedApp.container);
484
421
  if (bDestroy) {
485
- return this.destroyApplication(oRestrictedApp.appId, oRestrictedApp.container);
422
+ // todo: [FLPCOREANDUX-10024] what is the actual difference between destroyApplication and handleExitStateful?
423
+ return this._destroyApplication(oRestrictedApp.appId, oRestrictedApp.container);
486
424
  }
487
425
 
488
- return this.handleExitStateful(oRestrictedApp.appId, oRestrictedApp.container, true, true);
426
+ return this._handleExitStateful(oRestrictedApp.container, true, true);
489
427
  });
490
428
 
491
429
  return Promise.all(aClosePromises);
@@ -499,9 +437,21 @@ sap.ui.define([
499
437
  * @param {object} oFrom
500
438
  */
501
439
  this.onBeforeNavigate = function (sFromId, oFrom) {
502
- if (sFromId && oFrom?._getIFrame?.() && oFrom?.getStatefulType?.() > BlueBoxHandler.STATEFUL_TYPES.NOT_SUPPORTED || Storage.get(sFromId)) {
503
- PostMessageUtils.postMessageToIframeApp(oFrom, "sap.ushell.sessionHandler", "beforeApplicationHide", {}, false);
440
+ if (sFromId && oFrom && oFrom.isA("sap.ushell.components.container.ApplicationContainer")) {
441
+ const sStorageAppId = sFromId;
442
+ const oApplicationContainer = oFrom;
443
+
444
+ const bHasIframe = !!oApplicationContainer._getIFrame(); // todo: [FLPCOREANDUX-10024] is this really required?
445
+ const bIsSupportedType = oApplicationContainer.getStatefulType() > BlueBoxHandler.STATEFUL_TYPES.NOT_SUPPORTED;
446
+
447
+ const bCached = !!Storage.get(sStorageAppId);
448
+ const bSessionHandlingSupported = bHasIframe && bIsSupportedType;
449
+
450
+ if (bCached || bSessionHandlingSupported) {
451
+ PostMessageUtils.postMessageToIframeApp(oApplicationContainer, "sap.ushell.sessionHandler", "beforeApplicationHide", {}, false);
452
+ }
504
453
  }
454
+
505
455
  };
506
456
 
507
457
  /**
@@ -510,63 +460,128 @@ sap.ui.define([
510
460
  * @param {string} sToId
511
461
  * @param {object} oTo
512
462
  */
513
- this.onAfterNavigate = function (sFromId, oFrom, sToId, oTo) { //call lifecycle interface "setInitialConfiguration"
463
+ this.onAfterNavigate = async function (sFromId, oFrom, sToId, oTo) { //call lifecycle interface "setInitialConfiguration"
464
+ if (!sToId) {
465
+ sToId = "";
466
+ }
467
+ if (!sFromId) {
468
+ sFromId = "";
469
+ }
514
470
  //destroy the application if not cached or marked for reuse.
515
- const bIsShellApps = sToId.indexOf("Shell-appfinder-component") > 0
516
- || sToId.indexOf("Shell-home-component") > 0
517
- || sToId.indexOf("pages-component-container") > 0
518
- || sToId.indexOf("homeApp-component-container") > 0
519
- || sToId.indexOf("workPageRuntime-component-container") > 0
520
- || sToId.indexOf("runtimeSwitcher-component-container") > 0;
521
-
522
- this.handleExitApplication(sFromId, oFrom, sToId, oTo, bIsShellApps, true);
523
- if (bIsShellApps) {
471
+ const aFlpComponentIds = [
472
+ "Shell-appfinder-component",
473
+ "Shell-home-component",
474
+ "pages-component-container",
475
+ "homeApp-component-container",
476
+ "workPageRuntime-component-container",
477
+ "runtimeSwitcher-component-container"
478
+ ];
479
+
480
+ const bNavigationToFlpComponent = aFlpComponentIds.some((sFlpComponentId) => sToId.includes(sFlpComponentId));
481
+ const bNavigationFromFlpComponent = aFlpComponentIds.some((sFlpComponentId) => sFromId.includes(sFlpComponentId));
482
+
483
+ if (bNavigationToFlpComponent) {
484
+ await this._closeKeepAliveApps((oStorageEntry) => oStorageEntry.keepAliveMode === KEEP_ALIVE_MODES.RESTRICTED);
485
+
524
486
  Application.setActiveAppContainer(undefined);
487
+
488
+ // Clear custom About Dialog parameters
489
+ AppInfoParameters.flush();
490
+ } else if (sToId && oTo) {
491
+ const sStorageAppId = sToId;
492
+ const oApplicationContainer = oTo;
493
+
494
+ // this code must be at the beginning of the function to allow it to be processed once in
495
+ // a cycle of opening an app
496
+ if (oApplicationContainer.getIframeReusedForApp()) {
497
+ oApplicationContainer.setProperty("iframeReusedForApp", false, true);
498
+ PostMessageUtils.postMessageToIframeApp(oApplicationContainer, "sap.ushell.sessionHandler", "afterApplicationShow", {}, false);
499
+ }
500
+
501
+ if (Storage.get(sStorageAppId)) {
502
+ this._restore(sStorageAppId);
503
+ }
525
504
  }
526
505
 
527
- // invoke the life cycle interface "setInitialConfiguration" for the restored application
528
- if (sToId) {
529
- if (Storage.get(sToId)) {
530
- this.restore(sToId);
531
- } else {
532
- // this application is not cached
533
- // here we can place code that handles the starting of the application in the after navigation life cycle.
506
+ if (bNavigationFromFlpComponent) {
507
+ //handle the case of appFinder
508
+ if (sToId.indexOf("Shell-appfinder-component") > 0) {
509
+ EventBus.getInstance().publish("sap.ushell", "appFinderAfterNavigate");
510
+ }
511
+
512
+ if (bDisableHomeAppCache) {
513
+ try {
514
+ this._removeApplicationContainerFromViewPort(sFromId);
515
+ oFrom.destroy();
516
+ } catch (oError) {
517
+ Log.error(`Error when trying to destroy the home component: '${sToId}'`, oError);
518
+ }
534
519
  }
520
+ } else if (sFromId && oFrom) {
521
+ const oApplicationContainer = oFrom;
522
+
523
+ await this._handleExitApplication(oApplicationContainer, bNavigationToFlpComponent, true);
535
524
  }
525
+
526
+ RelatedServices.resetBackNavigationFlag();
536
527
  };
537
528
 
538
529
  /**
539
- * @param {string} sAppId
540
- * @param {object} oContainer
541
- * @param {object} oTarget
542
- * @param {string} sFixedShellHash
543
- * @param {object} oKeepAliveMode
544
- * @returns {boolean} Returns true if the app was stored
530
+ * @param {object} oOldResolvedHashFragment
531
+ * @param {object} oResolvedHashFragment
532
+ * @returns {Promise} Resolves when the after navigation was handled.
545
533
  */
546
- this.storeApp = function (sAppId, oContainer, oTarget, sFixedShellHash, oKeepAliveMode) {
547
- if (!this.isAppInCache(sAppId)) {
548
- if (oContainer.setProperty) {
549
- oContainer.setProperty("isKeepAlive", true, true);
534
+ // todo: [FLPCOREANDUX-10024] should be moved to onAfterNavigate
535
+ this.handleAfterNavigate = async function (oResolvedHashFragment, oOldResolvedHashFragment) {
536
+ if (!oOldResolvedHashFragment) {
537
+ return;
538
+ }
539
+
540
+ const sAppFrameworkId = ObjectPath.get("appCapabilities.appFrameworkId", oOldResolvedHashFragment);
541
+ const bFromApplicationIsTR = ushellUtils.isTRApplicationType(oOldResolvedHashFragment.applicationType, sAppFrameworkId);
542
+ const bToApplicationIsTR = ushellUtils.isTRApplicationType(oResolvedHashFragment.applicationType);
543
+
544
+ if (bFromApplicationIsTR && !bToApplicationIsTR) {
545
+ const oPreviousStatefulContainer = BlueBoxHandler.getBlueBoxByUrl(oOldResolvedHashFragment.url);
546
+ if (oPreviousStatefulContainer && oPreviousStatefulContainer.getStatefulType() === BlueBoxHandler.STATEFUL_TYPES.GUI_V1) {
547
+ return WebGUIStatefulHandler.guiStatefulCloseCurrentApp(oPreviousStatefulContainer);
550
548
  }
551
- Storage.set(sAppId, {
552
- service: {},
553
- shellHash: sFixedShellHash,
554
- appId: sAppId,
555
- stt: "loading",
556
- currentState: null, // current state is stored before close see: sap/ushell/state/CurrentState
557
- controlManager: null, // control manager state is stored before close see: sap/ushell/state/ControlManager
558
- container: oContainer,
559
- meta: AppConfiguration.getMetadata(oTarget),
560
- app: undefined,
561
- keepAliveMode: oKeepAliveMode?.globalValue || oKeepAliveMode?.paramValue,
562
- appTarget: oTarget,
563
- ui5ComponentName: oTarget?.ui5ComponentName,
564
- enableRouterRetrigger: bEnableRouterRetrigger,
565
- stateStored: false
566
- });
567
- return true;
568
549
  }
569
- return false;
550
+ };
551
+
552
+ /**
553
+ * @param {string} sStorageAppId
554
+ * @param {object} oApplicationContainer
555
+ * @param {object} oResolvedHashFragment
556
+ * @param {string} oParsedShellHash
557
+ * @param {string} sKeepAliveMode
558
+ * @returns {boolean} Returns true if the app was stored
559
+ */
560
+ this._storeApp = function (sStorageAppId, oApplicationContainer, oResolvedHashFragment, oParsedShellHash, sKeepAliveMode) {
561
+ if (Storage.get(sStorageAppId)) {
562
+ return false;
563
+ }
564
+
565
+ oApplicationContainer.setProperty("isKeepAlive", true, true);
566
+
567
+ Storage.set(sStorageAppId, {
568
+ service: {},
569
+ shellHash: `#${UrlParsing.constructShellHash(oParsedShellHash)}`,
570
+ appId: sStorageAppId,
571
+ stt: "loading",
572
+ currentState: null, // current state is stored before close see: sap/ushell/state/CurrentState
573
+ controlManager: null, // control manager state is stored before close see: sap/ushell/state/ControlManager
574
+ container: oApplicationContainer,
575
+ meta: AppConfiguration.getMetadata(oResolvedHashFragment),
576
+ app: undefined,
577
+ keepAliveMode: sKeepAliveMode,
578
+ appTarget: oResolvedHashFragment,
579
+ ui5ComponentName: oResolvedHashFragment.ui5ComponentName,
580
+ enableRouterRetrigger: bEnableRouterRetrigger,
581
+ stateStored: false
582
+ });
583
+
584
+ return true;
570
585
  };
571
586
 
572
587
  /**
@@ -584,17 +599,16 @@ sap.ui.define([
584
599
  if (!oCurrentApp) {
585
600
  return;
586
601
  }
587
- const sAppId = oCurrentApp.appId;
588
- const oContainer = oCurrentApp.container;
589
-
590
- const oStorageEntry = Storage.get(sAppId);
602
+ const sStorageAppId = oCurrentApp.appId;
603
+ const oStorageEntry = Storage.get(sStorageAppId);
591
604
 
592
605
  if (!oStorageEntry) {
606
+ // do not store for non-keep-alive apps
593
607
  return;
594
608
  }
595
609
 
596
- if (oContainer?.getApplicationType() === "UI5") {
597
- await this.getComponentCreatedPromise(sAppId);
610
+ if (oStorageEntry.container.getApplicationType() === "UI5") {
611
+ await this._getComponentCreatedPromise(sStorageAppId);
598
612
  }
599
613
 
600
614
  // back navigation
@@ -603,97 +617,79 @@ sap.ui.define([
603
617
  AppMeta.store(oStorageEntry.meta);
604
618
  // currentState, controlManager
605
619
  KeepAlive.store(oStorageEntry);
620
+ // About Dialog
621
+ AppInfoParameters.store(oStorageEntry);
606
622
  };
607
623
 
608
624
  /**
609
- * @param {string} sAppId
610
- * @param {boolean} bIsAppOfTypeCachable
611
- * @param {object} oKeepAliveMode
612
- * @returns {boolean} Returns true if the app is of type cached.
625
+ * @param {string} sStorageAppId
626
+ * @param {object} oResolvedHashFragment
627
+ * @param {object} oParsedShellHash
628
+ * @returns {string} Returns the keep alive mode.
613
629
  */
614
- this.isAppOfTypeCached = function (sAppId, bIsAppOfTypeCachable, oKeepAliveMode) {
630
+ this._calculateKeepAliveMode = function (sStorageAppId, oResolvedHashFragment, oParsedShellHash) {
615
631
  //generic intent currently can never be keep alive
616
- if (sAppId === "application-Shell-startIntent") {
617
- return false;
618
- }
619
-
620
- //handle the root intent
621
- if (!bDisableHomeAppCache && sAppId.indexOf(sRootIntent) !== -1) {
622
- return true;
623
- }
624
-
625
- if (!bDisableHomeAppCache && sAppId.indexOf("Shell-appfinder") !== -1) {
626
- return true;
632
+ if (sStorageAppId === "application-Shell-startIntent") {
633
+ return;
627
634
  }
628
635
 
629
- //In order to enable application to play with the keep alive, we read the keep attribute of the hash, if it is true application is cachable.
630
- const sKeepAlive = new URLSearchParams(window.location.search).get("sap-keep-alive");
636
+ // Global override in query parameters
637
+ let sKeepAlive = new URLSearchParams(window.location.search).get("sap-keep-alive");
631
638
  if (sKeepAlive === KEEP_ALIVE_MODES.FULL || sKeepAlive === KEEP_ALIVE_MODES.RESTRICTED) {
632
- if (oKeepAliveMode) {
633
- oKeepAliveMode.globalValue = sKeepAlive;
634
- }
635
- return true;
636
- }
637
- return false;
638
- };
639
-
640
- /**
641
- * @param {object} oShellHash
642
- * @param {object} oTarget
643
- * @param {object} oKeepAliveMode
644
- * @returns {boolean} Returns true if the app should be cached.
645
- */
646
- this.isCachedEnabledAsAppParameter = function (oShellHash, oTarget, oKeepAliveMode) {
647
- let sKeepAlive;
648
-
649
- //generic intent currently can never be keep alive
650
- if (oShellHash?.semanticObject === "Shell" && oShellHash?.action === "startIntent") {
651
- return false;
639
+ return sKeepAlive;
640
+ } else if (sKeepAlive === KEEP_ALIVE_MODES.FALSE) {
641
+ return;
652
642
  }
653
643
 
654
- sKeepAlive = oShellHash?.params?.["sap-keep-alive"];
644
+ // App override in intent parameters
645
+ sKeepAlive = oParsedShellHash.params?.["sap-keep-alive"];
655
646
  if (sKeepAlive === KEEP_ALIVE_MODES.FULL || sKeepAlive === KEEP_ALIVE_MODES.RESTRICTED) {
656
- if (oKeepAliveMode) {
657
- oKeepAliveMode.paramValue = sKeepAlive;
658
- }
659
- return true;
647
+ return sKeepAlive;
648
+ } else if (sKeepAlive === KEEP_ALIVE_MODES.FALSE) {
649
+ return;
660
650
  }
661
651
 
662
- if (oTarget?.url) {
663
- sKeepAlive = UriParameters.fromURL(oTarget.url).get("sap-keep-alive");
652
+ // Magic override in resolved hash fragment
653
+ if (oResolvedHashFragment.url) {
654
+ sKeepAlive = UriParameters.fromURL(oResolvedHashFragment.url).get("sap-keep-alive");
664
655
  if (sKeepAlive === KEEP_ALIVE_MODES.FULL || sKeepAlive === KEEP_ALIVE_MODES.RESTRICTED) {
665
- if (oKeepAliveMode) {
666
- oKeepAliveMode.paramValue = sKeepAlive;
667
- }
668
- return true;
656
+ return sKeepAlive;
657
+ } else if (sKeepAlive === KEEP_ALIVE_MODES.FALSE) {
658
+ return;
669
659
  }
670
660
  }
671
661
 
672
- return false;
662
+ // if the app is a root intent, it should be kept alive (e.g. workzone advanced)
663
+ // can be overridden by the above checks
664
+ const sShellHash = UrlParsing.constructShellHash(oParsedShellHash);
665
+ if (sShellHash && ushellUtils.isRootIntent(sShellHash)) {
666
+ return KEEP_ALIVE_MODES.FULL;
667
+ }
673
668
  };
674
669
 
675
670
  /**
676
- * @param {object} oTarget
671
+ * @param {object} oResolvedHashFragment
677
672
  * @returns {string} Returns the application type.
678
673
  */
679
- this.calculateAppType = function (oTarget) {
680
- if (oTarget.applicationType === "URL" && oTarget?.additionalInformation?.startsWith?.("SAPUI5.Component=")) {
674
+ this._calculateAppType = function (oResolvedHashFragment) {
675
+ if (oResolvedHashFragment.applicationType === "URL" && oResolvedHashFragment.additionalInformation?.startsWith?.("SAPUI5.Component=")) {
681
676
  return "SAPUI5";
682
677
  }
683
- return oTarget.applicationType;
678
+ return oResolvedHashFragment.applicationType;
684
679
  };
685
680
 
686
681
  /**
687
682
  * @param {object} oData
688
- * @returns {Promise} Resolves when the app is reloded.
683
+ * @returns {Promise} Resolves when the app is reloaded.
689
684
  */
690
- this.reloadCurrentApp = async function (oData) {
685
+ this._reloadCurrentApp = async function (oData) {
691
686
  const oTmpAppContainer = BlueBoxHandler.getBlueBoxById(oData.sAppContainerId);
692
687
  if (oTmpAppContainer) {
688
+ // todo: [FLPCOREANDUX-10024] this destroy/remove can be simplified
693
689
  const sTmpUrl = oTmpAppContainer.getUrl();
694
690
  BlueBoxHandler.removeCapabilities(oTmpAppContainer);
695
691
  Storage.removeByContainer(oTmpAppContainer);
696
- this.destroyApplication(oData.sAppContainerId, oTmpAppContainer);
692
+ await this._destroyApplication(oData.sAppContainerId, oTmpAppContainer);
697
693
  BlueBoxHandler.deleteBlueBoxByUrl(sTmpUrl);
698
694
  }
699
695
 
@@ -707,110 +703,107 @@ sap.ui.define([
707
703
 
708
704
  /**
709
705
  * @param {string} sAppId
710
- * @param {object} oTarget
711
- * @param {object} oShellHash
712
- * @param {object} sFixedShellHash
706
+ * @param {object} oResolvedHashFragment
707
+ * @param {object} oParsedShellHash
713
708
  */
714
- this.openApp = function (sAppId, oTarget, oShellHash, sFixedShellHash) {
715
- const bIsAppOfTypeCachable = CACHED_APP_TYPES.indexOf(oTarget.applicationType) >= 0;
716
- const oKeepAliveMode = {
717
- globalValue: undefined,
718
- paramValue: undefined
719
- };
720
- let oContainer,
721
- sIntent,
722
- oTmpAppContainer,
723
- oContainerToUse,
709
+ this._openApp = async function (sAppId, oResolvedHashFragment, oParsedShellHash) {
710
+ let oTmpAppContainer,
711
+ oApplicationContainerToUse,
724
712
  sTmpUrl;
725
713
 
726
714
  //format appId, the is the storage identifier
727
- const appId = `application${sAppId}`;
715
+ const sStorageAppId = `application-${sAppId}`;
728
716
 
729
717
  //this case will handle the stateful containers flow.
730
- oContainer = BlueBoxHandler.getBlueBoxByUrl(oTarget.url);
718
+ let oApplicationContainer = BlueBoxHandler.getBlueBoxByUrl(oResolvedHashFragment.url);
731
719
 
732
- const bIsKeepAlive = this.isAppOfTypeCached(appId, bIsAppOfTypeCachable, oKeepAliveMode);
733
- const bIsCachedByParameter = this.isCachedEnabledAsAppParameter(oShellHash, oTarget, oKeepAliveMode);
720
+ const sKeepAliveMode = this._calculateKeepAliveMode(sStorageAppId, oResolvedHashFragment, oParsedShellHash);
721
+ const bShouldBeCached = !!sKeepAliveMode;
734
722
 
735
- if (BlueBoxHandler.isStatefulContainer(oContainer)) {
736
- if (bIsKeepAlive || bIsCachedByParameter) {
723
+ if (BlueBoxHandler.isStatefulContainer(oApplicationContainer)) {
724
+ if (bShouldBeCached) {
737
725
  //this is the case where we have a stateful container and keep alive
738
726
  //is cached application
739
- if (!this.isAppInCache(appId)) {
740
- this.storeApp(appId, oContainer, oTarget, sFixedShellHash, oKeepAliveMode);
741
- }
742
- if (this.isAppInCache(appId)) {
743
- oCurrentApplication = Storage.get(appId);
727
+ let oStorageEntry = Storage.get(sStorageAppId);
728
+ if (!oStorageEntry) {
729
+ this._storeApp(sStorageAppId, oApplicationContainer, oResolvedHashFragment, oParsedShellHash, sKeepAliveMode);
730
+ oStorageEntry = Storage.get(sStorageAppId);
744
731
  }
732
+
733
+ oCurrentApplication = oStorageEntry;
745
734
  } else {
746
735
  //create application that is not persisted and not cashed
747
736
  oCurrentApplication = {
748
- appId: appId,
737
+ appId: sStorageAppId,
749
738
  stt: "loading",
750
- container: oContainer,
751
- meta: AppConfiguration.getMetadata(oTarget),
739
+ container: oApplicationContainer,
740
+ meta: AppConfiguration.getMetadata(oResolvedHashFragment),
752
741
  app: undefined
753
742
  };
754
743
  }
755
- } else if (bIsKeepAlive || bIsCachedByParameter) {
744
+ } else if (bShouldBeCached) {
756
745
  //is cached application
757
- if (!this.isAppInCache(appId)) {
758
- oContainerToUse = BlueBoxHandler.findFreeContainerForNewKeepAliveApp(oTarget);
759
- if (!oContainerToUse) {
746
+ let oStorageEntry = Storage.get(sStorageAppId);
747
+ if (!oStorageEntry) {
748
+ oApplicationContainerToUse = BlueBoxHandler.findFreeContainerForNewKeepAliveApp(oResolvedHashFragment);
749
+ if (!oApplicationContainerToUse) {
760
750
  //in cFLP, there night me an existing container of the same app from a different server,
761
751
  //so we will need to destroy it to avoid duplicate id
762
- sIntent = `${oShellHash.semanticObject}-${oShellHash.action}`;
763
- oTmpAppContainer = BlueBoxHandler.getBlueBoxById(`application-${sIntent}`) || this.getControl(sIntent);
752
+ oTmpAppContainer = BlueBoxHandler.getBlueBoxById(sStorageAppId) || this._getApplicationContainerFromViewPort(sAppId);
753
+ // todo: [FLPCOREANDUX-10024] this destroy/remove can be simplified
764
754
  if (oTmpAppContainer) {
765
755
  sTmpUrl = oTmpAppContainer.getUrl();
766
756
  BlueBoxHandler.removeCapabilities(oTmpAppContainer);
767
- this.destroyApplication(`application-${sIntent}`, oTmpAppContainer);
757
+ await this._destroyApplication(sStorageAppId, oTmpAppContainer);
768
758
  BlueBoxHandler.deleteBlueBoxByUrl(sTmpUrl);
769
759
  }
770
- oContainer = Application.createApplicationContainer(sAppId, oTarget);
760
+ oApplicationContainer = Application.createApplicationContainer(sStorageAppId, oResolvedHashFragment);
771
761
  } else {
772
- oContainer = oContainerToUse;
762
+ oApplicationContainer = oApplicationContainerToUse;
773
763
  }
774
- this.storeApp(appId, oContainer, oTarget, sFixedShellHash, oKeepAliveMode);
775
- }
776
- if (this.isAppInCache(appId)) {
777
- oCurrentApplication = Storage.get(appId);
764
+
765
+ this._storeApp(sStorageAppId, oApplicationContainer, oResolvedHashFragment, oParsedShellHash, sKeepAliveMode);
766
+ oStorageEntry = Storage.get(sStorageAppId);
778
767
  }
779
- } else if (oTarget.applicationType === "TR" || oTarget?.appCapabilities?.appFrameworkId === "GUI") {
780
- oContainer = BlueBoxHandler.getBlueBoxByUrl(oTarget.url);
781
- if (oContainer?.getStatefulType && oContainer.getStatefulType() !== BlueBoxHandler.STATEFUL_TYPES.GUI_V1) {
782
- oContainer = undefined;
768
+
769
+ oCurrentApplication = oStorageEntry;
770
+ } else if (oResolvedHashFragment.applicationType === "TR" || oResolvedHashFragment.appCapabilities?.appFrameworkId === "GUI") {
771
+ oApplicationContainer = BlueBoxHandler.getBlueBoxByUrl(oResolvedHashFragment.url);
772
+ if (oApplicationContainer && oApplicationContainer.getStatefulType() !== BlueBoxHandler.STATEFUL_TYPES.GUI_V1) {
773
+ oApplicationContainer = undefined;
783
774
  }
784
775
 
785
776
  //in cFLP, there night me an existing container of the same app from a different server,
786
777
  //so we will need to destroy it to avoid duplicate id
787
- if (oShellHash) {
788
- sIntent = `${oShellHash.semanticObject}-${oShellHash.action}`;
789
- oTmpAppContainer = BlueBoxHandler.getBlueBoxById(`application-${sIntent}`) || this.getControl(sIntent);
790
- if (oTmpAppContainer && (!oContainer || oTmpAppContainer !== oContainer)) {
791
- sTmpUrl = oTmpAppContainer.getUrl();
792
- BlueBoxHandler.removeCapabilities(oTmpAppContainer);
793
- this.destroyApplication(`application-${sIntent}`, oTmpAppContainer);
794
- BlueBoxHandler.deleteBlueBoxByUrl(sTmpUrl);
795
- }
778
+ oTmpAppContainer = BlueBoxHandler.getBlueBoxById(sStorageAppId) || this._getApplicationContainerFromViewPort(sAppId);
779
+ // todo: [FLPCOREANDUX-10024] this destroy/remove can be simplified
780
+ if (oTmpAppContainer && (!oApplicationContainer || oTmpAppContainer !== oApplicationContainer)) {
781
+ sTmpUrl = oTmpAppContainer.getUrl();
782
+ BlueBoxHandler.removeCapabilities(oTmpAppContainer);
783
+ await this._destroyApplication(sStorageAppId, oTmpAppContainer);
784
+ BlueBoxHandler.deleteBlueBoxByUrl(sTmpUrl);
796
785
  }
797
786
 
798
- if (!oContainer) {
799
- oContainer = Application.createApplicationContainer(sAppId, oTarget);
787
+ if (!oApplicationContainer) {
788
+ oApplicationContainer = Application.createApplicationContainer(sStorageAppId, oResolvedHashFragment);
800
789
  }
801
790
  //create application that is not persisted and not cashed
802
791
  oCurrentApplication = {
803
- appId: appId,
792
+ appId: sStorageAppId,
804
793
  stt: "loading",
805
- container: oContainer,
806
- meta: AppConfiguration.getMetadata(oTarget),
794
+ container: oApplicationContainer,
795
+ meta: AppConfiguration.getMetadata(oResolvedHashFragment),
807
796
  app: undefined
808
797
  };
809
798
  } else {
810
- if (oContainer) {
811
- sIntent = `${oShellHash.semanticObject}-${oShellHash.action}`;
812
- this.removeApplication(sIntent);
813
- } else if (oTarget.applicationType === "URL" || oTarget.applicationType === "TR" || oTarget.applicationType === "NWBC") {
799
+ if (oApplicationContainer) {
800
+ const oApplicationContainer = this._getApplicationContainerFromViewPort(sAppId);
801
+
802
+ if (oApplicationContainer) {
803
+ this._removeApplicationContainerFromViewPort(oApplicationContainer.getId());
804
+ oApplicationContainer.destroy();
805
+ }
806
+ } else if (oResolvedHashFragment.applicationType === "URL" || oResolvedHashFragment.applicationType === "TR" || oResolvedHashFragment.applicationType === "NWBC") {
814
807
  //Temporary fix - fix duplicate app container id in cFLP
815
808
  //explanation: in cFLP, there might be a case where there are
816
809
  // two apps with the same Semantic object + Action, but from different
@@ -819,23 +812,23 @@ sap.ui.define([
819
812
  // we delete here the blue box and then create the new one.
820
813
  // In future BLI, we will change the id of the container to be
821
814
  // more unique.
822
- sIntent = `${oShellHash.semanticObject}-${oShellHash.action}`;
823
- oTmpAppContainer = BlueBoxHandler.getBlueBoxById(`application-${sIntent}`) || this.getControl(sIntent);
815
+ oTmpAppContainer = BlueBoxHandler.getBlueBoxById(sStorageAppId) || this._getApplicationContainerFromViewPort(sAppId);
824
816
  if (oTmpAppContainer) {
817
+ // todo: [FLPCOREANDUX-10024] this destroy/remove can be simplified
825
818
  sTmpUrl = oTmpAppContainer.getUrl();
826
819
  BlueBoxHandler.removeCapabilities(oTmpAppContainer);
827
- this.destroyApplication(`application-${sIntent}`, oTmpAppContainer, true);
820
+ await this._destroyApplication(sStorageAppId, oTmpAppContainer, true);
828
821
  BlueBoxHandler.deleteBlueBoxByUrl(sTmpUrl);
829
822
  }
830
823
  }
831
- oContainer = Application.createApplicationContainer(sAppId, oTarget);
824
+ oApplicationContainer = Application.createApplicationContainer(sStorageAppId, oResolvedHashFragment);
832
825
 
833
826
  // //create application that is not persisted and not cashed
834
827
  oCurrentApplication = {
835
- appId: appId,
828
+ appId: sStorageAppId,
836
829
  stt: "loading",
837
- container: oContainer,
838
- meta: AppConfiguration.getMetadata(oTarget),
830
+ container: oApplicationContainer,
831
+ meta: AppConfiguration.getMetadata(oResolvedHashFragment),
839
832
  app: undefined
840
833
  };
841
834
  }
@@ -845,7 +838,7 @@ sap.ui.define([
845
838
  * Any event one wishes to subscribe to during the AppLifeCycle.init() call should be added here.
846
839
  * Events will only be added the first time AppLifeCycle.init() is called.
847
840
  */
848
- this.addEvents = (function () {
841
+ this._addEvents = (function () {
849
842
  let hasBeenCalled = false;
850
843
  return function () {
851
844
  if (!hasBeenCalled) {
@@ -853,21 +846,21 @@ sap.ui.define([
853
846
 
854
847
  // Subscribe to events.
855
848
  EventHub.on("disableKeepAliveRestoreRouterRetrigger").do((oData) => {
856
- const sIntent = `${oData.intent.semanticObject}-${oData.intent.action}`;
857
- const sAppId = `application-${sIntent}`;
849
+ const sAppId = `${oData.intent.semanticObject}-${oData.intent.action}`;
850
+ const sStorageAppId = `application-${sAppId}`;
858
851
 
859
852
  bEnableRouterRetrigger = oData.disable;
860
853
 
861
- if (Storage.get(sAppId)) {
862
- Storage.get(sAppId).enableRouterRetrigger = oData.disable;
854
+ if (Storage.get(sStorageAppId)) {
855
+ Storage.get(sStorageAppId).enableRouterRetrigger = oData.disable;
863
856
  }
864
857
  });
865
858
  EventHub.on("setApplicationFullWidth").do((oData) => {
866
- this.setApplicationFullWidth(oData.bValue);
859
+ this._setApplicationFullWidth(oData.bValue);
867
860
  });
868
861
 
869
862
  EventHub.on("reloadCurrentApp").do((oData) => {
870
- this.reloadCurrentApp(oData);
863
+ this._reloadCurrentApp(oData);
871
864
  });
872
865
  }
873
866
  };
@@ -875,10 +868,9 @@ sap.ui.define([
875
868
 
876
869
  /**
877
870
  * @param {object} oInViewPortContainer
878
- * @param {string} sInRootIntent
879
871
  * @param {boolean} bInDisableHomeAppCache
880
872
  */
881
- this.init = function (oInViewPortContainer, sInRootIntent, bInDisableHomeAppCache) {
873
+ this.init = function (oInViewPortContainer, bInDisableHomeAppCache) {
882
874
  if (Container && Config.last("/core/shell/enablePersistantAppstateWhenSharing")) {
883
875
  Container.getServiceAsync("AppState").then((oAppStateService) => {
884
876
  fnOldTriggerEmail = URLHelper.triggerEmail.bind(URLHelper);
@@ -908,7 +900,6 @@ sap.ui.define([
908
900
  this._createGlobalShellUIService();
909
901
 
910
902
  oViewPortContainer = oInViewPortContainer;
911
- sRootIntent = sInRootIntent;
912
903
  bDisableHomeAppCache = bInDisableHomeAppCache;
913
904
 
914
905
  BlueBoxHandler.init();
@@ -946,18 +937,18 @@ sap.ui.define([
946
937
  setup: {
947
938
  executeServiceCallFn: async function (oServiceParams) {
948
939
  const oSetup = oServiceParams?.oMessageData?.body;
949
- const { oContainer } = oServiceParams;
940
+ const { oContainer: oApplicationContainer } = oServiceParams;
950
941
 
951
942
  const arrCap = [];
952
943
  let bIgnoreStateful = false;
953
944
  if (oSetup) {
954
- const bIsSAPLegacyApplicationType = ushellUtils.isSAPLegacyApplicationType(oContainer.getApplicationType(), oContainer.getFrameworkId());
955
- if (oContainer.getIsKeepAlive() && bIsSAPLegacyApplicationType) {
945
+ const bIsSAPLegacyApplicationType = ushellUtils.isSAPLegacyApplicationType(oApplicationContainer.getApplicationType(), oApplicationContainer.getFrameworkId());
946
+ if (oApplicationContainer.getIsKeepAlive() && bIsSAPLegacyApplicationType) {
956
947
  bIgnoreStateful = true;
957
948
  }
958
949
  if (oSetup.isStateful) {
959
950
  if (bIgnoreStateful) {
960
- oContainer.setProperty("statefulType", -BlueBoxHandler.STATEFUL_TYPES.FLP_V2, true);
951
+ oApplicationContainer.setProperty("statefulType", -BlueBoxHandler.STATEFUL_TYPES.FLP_V2, true);
961
952
  } else {
962
953
  arrCap.push({
963
954
  action: "create",
@@ -967,7 +958,7 @@ sap.ui.define([
967
958
  action: "destroy",
968
959
  service: "sap.ushell.services.AppLifeCycle"
969
960
  });
970
- oContainer.setProperty("statefulType", BlueBoxHandler.STATEFUL_TYPES.FLP_V2, true);
961
+ oApplicationContainer.setProperty("statefulType", BlueBoxHandler.STATEFUL_TYPES.FLP_V2, true);
971
962
  }
972
963
  }
973
964
  if (oSetup.isIframeValid) {
@@ -977,7 +968,7 @@ sap.ui.define([
977
968
  arrCap.push({ action: "logout", service: "sap.ushell.sessionHandler" });
978
969
  }
979
970
  if (arrCap.length > 0) {
980
- BlueBoxHandler.addCapabilities(oContainer, arrCap);
971
+ BlueBoxHandler.addCapabilities(oApplicationContainer, arrCap);
981
972
  }
982
973
  }
983
974
  }
@@ -988,19 +979,19 @@ sap.ui.define([
988
979
  oServiceCalls: {
989
980
  loadFinished: {
990
981
  executeServiceCallFn: async function (oServiceParams) {
991
- const { oContainer } = oServiceParams;
982
+ const { oContainer: oApplicationContainer } = oServiceParams;
992
983
 
993
- if (!oContainer.getIsKeepAlive()) {
994
- oContainer.setProperty("statefulType", BlueBoxHandler.STATEFUL_TYPES.GUI_V1, true);
984
+ if (!oApplicationContainer.getIsKeepAlive()) {
985
+ oApplicationContainer.setProperty("statefulType", BlueBoxHandler.STATEFUL_TYPES.GUI_V1, true);
995
986
  oCurrentApplication = {
996
- appId: oContainer.getId(),
987
+ appId: oApplicationContainer.getId(),
997
988
  stt: "loading",
998
- container: oContainer,
989
+ container: oApplicationContainer,
999
990
  meta: undefined,
1000
991
  app: undefined
1001
992
  };
1002
993
  } else {
1003
- oContainer.setProperty("statefulType", -BlueBoxHandler.STATEFUL_TYPES.GUI_V1, true);
994
+ oApplicationContainer.setProperty("statefulType", -BlueBoxHandler.STATEFUL_TYPES.GUI_V1, true);
1004
995
  }
1005
996
  return {};
1006
997
  }
@@ -1011,10 +1002,10 @@ sap.ui.define([
1011
1002
  });
1012
1003
 
1013
1004
  //TODO add unsubscribe
1014
- EventBus.getInstance().subscribe("sap.ushell", "appComponentLoaded", this.onComponentCreated, this);
1015
- EventBus.getInstance().subscribe("sap.ushell", "getAppLifeCycle", this.onGetMe, this);
1005
+ EventBus.getInstance().subscribe("sap.ushell", "appComponentLoaded", this._onComponentCreated, this);
1006
+ EventBus.getInstance().subscribe("sap.ushell", "getAppLifeCycle", this._onGetMe, this);
1016
1007
 
1017
- this.addEvents();
1008
+ this._addEvents();
1018
1009
  };
1019
1010
 
1020
1011
  /**
@@ -1043,16 +1034,16 @@ sap.ui.define([
1043
1034
  };
1044
1035
 
1045
1036
  /**
1046
- * @param {object} oControl
1037
+ * @param {object} oApplicationContainer
1047
1038
  */
1048
- this.addControl = function (oControl) {
1049
- oViewPortContainer.addCenterViewPort(oControl);
1039
+ this._addApplicationContainerToViewPort = function (oApplicationContainer) {
1040
+ oViewPortContainer.addCenterViewPort(oApplicationContainer);
1050
1041
  };
1051
1042
 
1052
1043
  /**
1053
1044
  * @param {string} sId
1054
1045
  */
1055
- this.removeControl = function (sId) {
1046
+ this._removeApplicationContainerFromViewPort = function (sId) {
1056
1047
  const oBlueBox = BlueBoxHandler.getBlueBoxById(sId);
1057
1048
  const bIsStateful = BlueBoxHandler.isStatefulContainer(oBlueBox);
1058
1049
 
@@ -1062,38 +1053,28 @@ sap.ui.define([
1062
1053
  };
1063
1054
 
1064
1055
  /**
1065
- * @param {string} sIntent
1066
- */
1067
- this.removeApplication = function (sIntent) {
1068
- const oInnerControl = this.getControl(sIntent);
1069
-
1070
- if (oInnerControl) {
1071
- this.removeControl(oInnerControl.getId());
1072
- oInnerControl.destroy();
1073
- }
1074
- };
1075
-
1076
- /**
1077
- * @param {string} sIntent
1056
+ * @param {string} sAppId
1078
1057
  * @returns {object} Returns the control.
1079
1058
  */
1080
- this.getControl = function (sIntent) {
1081
- return oViewPortContainer
1082
- && (oViewPortContainer.getViewPortControl("centerViewPort", `application-${sIntent}`)
1083
- || oViewPortContainer.getViewPortControl("centerViewPort", `applicationShellPage-${sIntent}`));
1059
+ this._getApplicationContainerFromViewPort = function (sAppId) {
1060
+ if (!oViewPortContainer) {
1061
+ return;
1062
+ }
1063
+ return oViewPortContainer.getViewPortControl("centerViewPort", `application-${sAppId}`)
1064
+ || oViewPortContainer.getViewPortControl("centerViewPort", `applicationShellPage-${sAppId}`);
1084
1065
  };
1085
1066
 
1086
1067
  /**
1087
1068
  * @returns {object} Returns the view port container.
1088
1069
  */
1089
- this.getViewPortContainer = function () {
1070
+ this._getViewPortContainer = function () {
1090
1071
  return oViewPortContainer;
1091
1072
  };
1092
1073
 
1093
1074
  /**
1094
1075
  * @param {string} sId
1095
1076
  */
1096
- this.navTo = function (sId) {
1077
+ this._navTo = function (sId) {
1097
1078
  oViewPortContainer.navTo("centerViewPort", sId, "show");
1098
1079
  };
1099
1080
 
@@ -1113,7 +1094,7 @@ sap.ui.define([
1113
1094
  /**
1114
1095
  * @param {boolean} bIsFull
1115
1096
  */
1116
- this.setApplicationFullWidth = function (bIsFull) {
1097
+ this._setApplicationFullWidth = function (bIsFull) {
1117
1098
  const oCurrent = this.getCurrentApplication();
1118
1099
 
1119
1100
  //validate that we have a valid applicationContainer
@@ -1122,69 +1103,20 @@ sap.ui.define([
1122
1103
  }
1123
1104
  };
1124
1105
 
1125
- // FIXME: It would be better to call a function that simply
1126
- // and intentionally loads the dependencies of the UI5
1127
- // application, rather than creating a component and expecting
1128
- // the dependencies to be loaded as a side effect.
1129
- // Moreover, the comment reads "load ui5 component via shell service"
1130
- // however that is 'not needed' since the loaded component
1131
- // is not used. We should evaluate the possible performance
1132
- // hit taken due to this implicit means to an end.
1133
1106
  /**
1134
- * @param {object} oResolvedHashFragment
1135
- * @param {object} oParsedShellHash
1136
- * @returns {Promise} Resolves when the component is created.
1107
+ * Returns the global ShellUIService instance.
1108
+ * @returns {object} The global ShellUIService instance
1137
1109
  */
1138
- this.createComponent = async function (oResolvedHashFragment, oParsedShellHash) {
1139
- function fnCloseKeepAliveIfSameUI5App (oApp) {
1140
- return (oApp.ui5ComponentName === oResolvedHashFragment.ui5ComponentName);
1141
- }
1142
-
1143
- await this.closeKeepAliveApps(fnCloseKeepAliveIfSameUI5App);
1144
-
1145
- await Application.createComponent(oResolvedHashFragment, oParsedShellHash);
1110
+ this.getShellUIService = function () {
1111
+ return oGlobalShellUIService;
1146
1112
  };
1147
1113
 
1148
1114
  /**
1149
- * @param {string} sAppId
1150
- * @param {object} oResolvedNavigationTarget
1151
- * @param {boolean} bIsColdStart
1152
- * @param {object} oShellHash
1153
- * @param {string} sFixedShellHash
1154
- * @returns {object}
1155
1115
  */
1156
- this.getAppContainer = function (sAppId, oResolvedNavigationTarget, bIsColdStart, oShellHash, sFixedShellHash) {
1157
- oResolvedNavigationTarget.shellUIService = oGlobalShellUIService.getInterface();
1158
-
1159
- /*
1160
- * The external navigation mode in the resolution result is calculated
1161
- * statically, and indicates a future state. It currently answers the
1162
- * question: "is the application going to be opened explace?".
1163
- *
1164
- * The target navigation mode, instead, answers the question: "was
1165
- * the application opened explace?".
1166
- *
1167
- * We need to have this logic, because embedded applications do not
1168
- * check the coldstart condition.
1169
- */
1170
- oResolvedNavigationTarget.targetNavigationMode = bIsColdStart ? "explace" : "inplace";
1171
-
1172
- this.openApp(sAppId, oResolvedNavigationTarget, oShellHash, sFixedShellHash);
1173
- if (oGlobalShellCommunicationHandlers.length > 0) {
1174
- oCurrentApplication.container.registerShellCommunicationHandler(oGlobalShellCommunicationHandlers);
1175
- }
1176
- if (oGlobalIframeCommunicationHandlers.UI5APP) {
1177
- oCurrentApplication.container.setIframeHandlers(oGlobalIframeCommunicationHandlers.UI5APP);
1116
+ this.resetGlobalShellUIService = function () {
1117
+ if (oGlobalShellUIService) {
1118
+ oGlobalShellUIService.resetService();
1178
1119
  }
1179
- return oCurrentApplication.container;
1180
- };
1181
-
1182
- /**
1183
- * Returns the global ShellUIService instance.
1184
- * @returns {object} The global ShellUIService instance
1185
- */
1186
- this.getShellUIService = function () {
1187
- return oGlobalShellUIService;
1188
1120
  };
1189
1121
 
1190
1122
  /**
@@ -1213,66 +1145,51 @@ sap.ui.define([
1213
1145
  * This method sets only one container as active and de-activates all
1214
1146
  * other application containers around.
1215
1147
  *
1216
- * @param {object} oApplicationContainer
1148
+ * @param {object} oTargetApplicationContainer
1217
1149
  * The application container to activate. Pass <code>null</code> in
1218
1150
  * case no application container must be activated.
1219
1151
  *
1220
1152
  * @private
1221
1153
  */
1222
- this.activeContainer = function (oApplicationContainer) {
1223
- BlueBoxHandler.forEach((oAppContainer) => {
1224
- if (oAppContainer && oAppContainer !== oApplicationContainer) {
1154
+ this._activeContainer = function (oTargetApplicationContainer) {
1155
+ BlueBoxHandler.forEach((oApplicationContainer) => {
1156
+ if (oApplicationContainer && oApplicationContainer !== oTargetApplicationContainer) {
1225
1157
  try {
1226
- Log.info(`Deactivating container ${oAppContainer.getId()}`);
1227
- oAppContainer.setActive(false);
1158
+ Log.info(`Deactivating container ${oApplicationContainer.getId()}`);
1159
+ oApplicationContainer.setActive(false);
1228
1160
  } catch (e) {
1229
1161
  /* empty */
1230
1162
  }
1231
1163
  }
1232
1164
  });
1233
1165
 
1234
- if (oApplicationContainer) {
1235
- Log.info(`Activating container "${oApplicationContainer.getId()}"`);
1236
- oApplicationContainer.setActive(true);
1166
+ if (oTargetApplicationContainer) {
1167
+ Log.info(`Activating container "${oTargetApplicationContainer.getId()}"`);
1168
+ oTargetApplicationContainer.setActive(true);
1237
1169
  }
1238
1170
  };
1239
1171
 
1240
1172
  /**
1241
1173
  * @param {object} oApplicationContainer
1242
- */
1243
- this.showApplicationContainer = function (oApplicationContainer) {
1244
- this.navTo(oApplicationContainer.getId());
1245
- //Added this because in cases when navigating to the same id (can happen when stateful container, I need the on onAfterNavigate)
1246
- if (oApplicationContainer.hasStyleClass("sapUShellApplicationContainerShiftedIframe")) {
1247
- oApplicationContainer.toggleStyleClass("sapUShellApplicationContainerIframeHidden", false);
1248
- } else {
1249
- oApplicationContainer.toggleStyleClass("hidden", false);
1250
- }
1251
- Application.setActiveAppContainer(oApplicationContainer);
1252
- Log.info("New application context opened successfully in an existing transaction UI session.");
1253
- };
1254
-
1255
- /**
1256
- * @param {object} oAppContainer
1257
1174
  * @param {object} oApplication
1258
1175
  * @param {function} fnOnAfterRendering
1259
1176
  */
1260
- this.publishNavigationStateEvents = function (oAppContainer, oApplication, fnOnAfterRendering) {
1177
+ this._publishNavigationStateEvents = function (oApplicationContainer, oApplication, fnOnAfterRendering) {
1261
1178
  //after the app container is rendered, publish an event to notify
1262
1179
  //that an app was opened
1263
- const sId = oAppContainer.getId ? oAppContainer.getId() : "";
1180
+ const sId = oApplicationContainer.getId ? oApplicationContainer.getId() : "";
1264
1181
  const appMetaData = AppConfiguration.getMetadata();
1265
1182
  const sIcon = appMetaData.icon;
1266
1183
  const sTitle = appMetaData.title;
1267
1184
 
1268
1185
  //Attach an event handler which will be called onAfterRendering
1269
- oAppContainer.addEventDelegate({ onAfterRendering: fnOnAfterRendering });
1186
+ oApplicationContainer.addEventDelegate({ onAfterRendering: fnOnAfterRendering });
1270
1187
 
1271
1188
  //after the app container exit, publish an event to notify
1272
1189
  //that an app was closed
1273
1190
  const that = this;
1274
- const origExit = oAppContainer.exit;
1275
- oAppContainer.exit = function () {
1191
+ const origExit = oApplicationContainer.exit;
1192
+ oApplicationContainer.exit = function () {
1276
1193
  if (origExit) {
1277
1194
  origExit.apply(this, arguments);
1278
1195
  }
@@ -1320,37 +1237,25 @@ sap.ui.define([
1320
1237
  };
1321
1238
 
1322
1239
  /**
1323
- * @param {string} sIntent
1324
- * @param {string} sFixedShellHash
1325
- * @param {string} sAppPart
1326
- * @param {string} sOldShellHash
1240
+ * @param {string} sAppId
1241
+ * @param {string} sShellHash
1242
+ * @param {boolean} bNavigationFromHome
1243
+ * @param {boolean} bNavigationWithInnerAppRoute
1327
1244
  * @returns {object}
1328
1245
  */
1329
- this.getInMemoryInstance = function (sIntent, sFixedShellHash, sAppPart, sOldShellHash) {
1330
- const sFullAppId = `application-${sIntent}`;
1331
- const oAppEntry = Storage.get(sFullAppId);
1332
- let sOldShellHashLowerCase = "";
1333
- let bNavigateToHomepage = false;
1334
- let bNavigatingFromHomeWithAppState;
1246
+ this._getInMemoryInstance = function (sAppId, sShellHash, bNavigationFromHome, bNavigationWithInnerAppRoute) {
1247
+ const sStorageAppId = `application-${sAppId}`;
1248
+ const oAppEntry = Storage.get(sStorageAppId);
1335
1249
 
1336
1250
  //remove application from cache if has different parameters
1337
1251
  if (oAppEntry) {
1338
1252
  //Special case - when we're navigating from homepage to an application with state, when keep-alive
1339
1253
  //is active. In this case, although keep alive is active we need to destroy the application
1340
1254
  //ans re-open it.
1341
- if (sOldShellHash !== null && sOldShellHash !== undefined && sOldShellHash !== "") {
1342
- sOldShellHashLowerCase = sOldShellHash.toLowerCase();
1343
- //All option to verify that we're navigating from the home page
1344
- bNavigateToHomepage = sOldShellHashLowerCase.indexOf("shell-home") >= 0 ||
1345
- sOldShellHashLowerCase.indexOf("launchpad-openflppage") >= 0 ||
1346
- sOldShellHashLowerCase.indexOf("launchpad-openworkpage") >= 0 ||
1347
- sOldShellHashLowerCase.indexOf("shell-appfinder") >= 0;
1348
- }
1255
+ const bNavigatingFromHomeWithAppState = bNavigationFromHome && bNavigationWithInnerAppRoute;
1256
+ // todo: [FLPCOREANDUX-10024] Add logging
1349
1257
 
1350
- bNavigatingFromHomeWithAppState = (bNavigateToHomepage &&
1351
- (typeof sAppPart === "string" && sAppPart.length > 0));
1352
-
1353
- if (oAppEntry.shellHash === sFixedShellHash && !bNavigatingFromHomeWithAppState) {
1258
+ if (oAppEntry.shellHash === sShellHash && !bNavigatingFromHomeWithAppState) {
1354
1259
  return {
1355
1260
  isInstanceSupported: true,
1356
1261
  appId: oAppEntry.appId,
@@ -1372,86 +1277,98 @@ sap.ui.define([
1372
1277
  };
1373
1278
 
1374
1279
  /**
1375
- * @param {boolean} bIsInitial
1376
- * @param {boolean} bIsInCache
1377
- * @param {string} sToId
1378
- * @param {object} oInnerControl
1379
- * @param {object} oTarget
1380
- * @param {string} sFixedShellHash
1381
- * @param {object} oKeepAliveMode
1280
+ * @param {boolean} bNewlyCreatedApplicationContainer
1281
+ * @param {boolean} bShouldBeCached
1282
+ * @param {string} sStorageAppId
1283
+ * @param {object} oApplicationContainer
1284
+ * @param {object} oResolvedHashFragment
1285
+ * @param {string} oParsedShellHash
1286
+ * @param {string} sKeepAliveMode
1382
1287
  * @param {boolean} bNavigationInSameStatefulContainer
1383
1288
  * @param {boolean} bReturnedFromKeepAlivePoolFLPV2
1384
1289
  * @returns {Promise} Resolves when the stateful app was opened.
1385
1290
  */ // eslint-disable-next-line max-len
1386
- this.handleOpenStateful = function (bIsInitial, bIsInCache, sToId, oInnerControl, oTarget, sFixedShellHash, oKeepAliveMode, bNavigationInSameStatefulContainer, bReturnedFromKeepAlivePoolFLPV2) {
1387
- let oPromise;
1388
-
1389
- oInnerControl.setProperty("iframeReusedForApp", true, true);
1390
- if (Storage.get(sToId) && !bIsInitial && !bReturnedFromKeepAlivePoolFLPV2) {
1391
- oPromise = BlueBoxHandler.statefulRestoreKeepAliveApp(oInnerControl, oTarget.url, sToId, oTarget, bNavigationInSameStatefulContainer)
1392
- .then(() => {
1393
- this.showApplicationContainer(oInnerControl);
1394
- })
1395
- .catch((vError) => {
1396
- Log.error(vError?.message || vError);
1397
- });
1398
- } else {
1399
- oPromise = BlueBoxHandler.statefulCreateApp(oInnerControl, oTarget.url, sToId, oTarget, bNavigationInSameStatefulContainer)
1400
- .then((oResult) => {
1401
- if (oResult?.deletedKeepAliveId) {
1402
- Storage.removeById(oResult.deletedKeepAliveId);
1403
- }
1404
- this.showApplicationContainer(oInnerControl);
1405
- })
1406
- .catch((vError) => {
1407
- Log.error(vError?.message || vError);
1408
- });
1291
+ this._handleOpenStateful = async function (bNewlyCreatedApplicationContainer, bShouldBeCached, sStorageAppId, oApplicationContainer, oResolvedHashFragment, oParsedShellHash, sKeepAliveMode, bNavigationInSameStatefulContainer, bReturnedFromKeepAlivePoolFLPV2) {
1292
+ oApplicationContainer.setProperty("iframeReusedForApp", true, true);
1293
+ try {
1294
+ if (Storage.get(sStorageAppId) && !bNewlyCreatedApplicationContainer && !bReturnedFromKeepAlivePoolFLPV2) {
1295
+ await BlueBoxHandler.statefulRestoreKeepAliveApp(oApplicationContainer, oResolvedHashFragment.url, sStorageAppId, oResolvedHashFragment, bNavigationInSameStatefulContainer);
1296
+ } else {
1297
+ const oResult = await BlueBoxHandler.statefulCreateApp(oApplicationContainer, oResolvedHashFragment.url, sStorageAppId, oResolvedHashFragment, bNavigationInSameStatefulContainer);
1298
+ if (oResult?.deletedKeepAliveId) {
1299
+ Storage.removeById(oResult.deletedKeepAliveId);
1300
+ }
1409
1301
 
1410
- //creating a new application check if needs to be keep (for the keep alive), and if so store the application
1411
- if (bIsInCache && !this.isAppInCache(sToId)) {
1412
- this.storeApp(sToId, oInnerControl, oTarget, sFixedShellHash, oKeepAliveMode);
1302
+ //creating a new application check if needs to be keep (for the keep alive), and if so store the application
1303
+ if (bShouldBeCached && !Storage.get(sStorageAppId)) {
1304
+ this._storeApp(sStorageAppId, oApplicationContainer, oResolvedHashFragment, oParsedShellHash, sKeepAliveMode);
1305
+ }
1413
1306
  }
1307
+
1308
+ Application.setActiveAppContainer(oApplicationContainer);
1309
+
1310
+ Log.info("New application context opened successfully in an existing transaction UI session.");
1311
+ } catch (vError) {
1312
+ Log.error(vError?.message || vError);
1313
+ // do not bubble up the error
1414
1314
  }
1315
+ };
1316
+
1317
+ this._isFullWidth = function (oResolvedHashFragment) {
1318
+ let bFullWidth;
1319
+ const sAppType = this._calculateAppType(oResolvedHashFragment);
1320
+ const bDefaultFullWidth = ApplicationType.getDefaultFullWidthSetting(sAppType);
1415
1321
 
1416
- return oPromise;
1322
+ const bFullWidthCapability = oResolvedHashFragment.appCapabilities?.fullWidth;
1323
+ const oMetadata = AppConfiguration.getMetadata(oResolvedHashFragment);
1324
+ //Here there's a double check for the fullwidth - once as a type of boolean and one as a string.
1325
+ //This is because we found that developers configured this variable in the manifest also as a string,
1326
+ //so the checks of the oMetadata and the oResolvedHashFragment are to avoid regression with the use of this field.
1327
+ if (bDefaultFullWidth) {
1328
+ if (oResolvedHashFragment.fullWidth === false || oResolvedHashFragment.fullWidth === "false" ||
1329
+ oMetadata.fullWidth === false || oMetadata.fullWidth === "false" || bFullWidthCapability === false) {
1330
+ bFullWidth = false;
1331
+ }
1332
+ } else if (oResolvedHashFragment.fullWidth || oResolvedHashFragment.fullWidth === "true" ||
1333
+ oMetadata.fullWidth || oMetadata.fullWidth === "true") {
1334
+ bFullWidth = true;
1335
+ }
1336
+
1337
+ if (bFullWidth === undefined) {
1338
+ bFullWidth = bDefaultFullWidth;
1339
+ }
1340
+ return bFullWidth;
1417
1341
  };
1418
1342
 
1419
1343
  /**
1420
- * @param {string} sIntent
1344
+ * formerly known as "handleControl"
1421
1345
  * @param {string} sAppId
1422
- * @param {object} oShellHash
1423
- * @param {object} oTarget
1424
- * @param {function} fnWrapper
1425
- * @param {string} sFixedShellHash
1426
- * @param {string} sOldFixedShellHash
1346
+ * @param {object} oParsedShellHash
1347
+ * @param {object} oResolvedHashFragment
1348
+ * @param {string} sOldShellHash
1427
1349
  * @returns {Promise} Resolves when the control is handled
1428
1350
  */
1429
- this.handleControl = async function (sIntent, sAppId, oShellHash, oTarget, fnWrapper, sFixedShellHash, sOldFixedShellHash) {
1351
+ this.handleCreateApplicationContainer = async function (sAppId, oParsedShellHash, oResolvedHashFragment, sOldShellHash) {
1430
1352
  let bReturnedFromKeepAlivePoolFLPV2 = false;
1431
1353
  let bReturnedFromKeepAlivePoolGuiV1 = false;
1432
- const bIsAppOfTypeCachable = CACHED_APP_TYPES.indexOf(oTarget.applicationType) >= 0;
1433
- const sFullAppId = `application-${sIntent}`;
1434
- let bIsInitial = false;
1435
- const oKeepAliveMode = {
1436
- globalValue: undefined,
1437
- paramValue: undefined
1438
- };
1354
+ const sStorageAppId = `application-${sAppId}`;
1355
+ let bNewlyCreatedApplicationContainer = false;
1439
1356
  let bNavigationInSameStatefulContainer = false;
1440
- let oInnerControl,
1357
+ let oApplicationContainer,
1441
1358
  bReuseStatefulContainer,
1442
1359
  oCurrentAppContainer,
1443
1360
  oOldAppStorageEntry,
1444
1361
  oTargetAppContainer,
1445
1362
  iLastValidTimeDelta,
1446
- oOldHash,
1447
- sOldFullAppId,
1363
+ sOldStorageAppId,
1448
1364
  sCurrentPageId,
1449
1365
  bKeptAliveApp,
1450
1366
  oCachedEntry;
1451
1367
 
1452
1368
  //get the potential target stateful container and check if it's valid. if not, destroy it
1453
1369
  //before we try to create the new application
1454
- oTargetAppContainer = BlueBoxHandler.getBlueBoxByUrl(oTarget.url);
1370
+ oTargetAppContainer = BlueBoxHandler.getBlueBoxByUrl(oResolvedHashFragment.url);
1371
+ // todo: [FLPCOREANDUX-10024] DELETES iframe
1455
1372
  if (BlueBoxHandler.isStatefulContainer(oTargetAppContainer)) {
1456
1373
  iLastValidTimeDelta = new Date().getTime() - oTargetAppContainer.getIsIframeValidTime().time;
1457
1374
  if ((BlueBoxHandler.isIframeIsValidSupported(oTargetAppContainer) && iLastValidTimeDelta >= 3500) ||
@@ -1462,27 +1379,30 @@ sap.ui.define([
1462
1379
  `reason: ${sReason}`,
1463
1380
  "sap.ushell.components.applicationIntegration.AppLifeCycle"
1464
1381
  );
1382
+
1383
+ // todo: [FLPCOREANDUX-10024] this destroy/remove can be simplified
1465
1384
  BlueBoxHandler.removeCapabilities(oTargetAppContainer);
1466
- this.destroyApplication(sFullAppId, oTargetAppContainer);
1467
- BlueBoxHandler.deleteBlueBoxByUrl(oTarget.url);
1385
+ await this._destroyApplication(sStorageAppId, oTargetAppContainer);
1386
+ BlueBoxHandler.deleteBlueBoxByUrl(oResolvedHashFragment.url);
1468
1387
  oTargetAppContainer = undefined;
1469
1388
  //in this case we do not care about the old application intent as it is currently relevant only when
1470
1389
  //trying to open app in the same current stateful container
1471
- sOldFixedShellHash = undefined;
1390
+ sOldShellHash = undefined;
1472
1391
  }
1473
1392
  }
1474
1393
 
1475
1394
  //get the application container object of the application we are leaving
1476
- if (typeof sOldFixedShellHash === "string") {
1477
- oOldHash = oUrlParsing.parseShellHash(sOldFixedShellHash);
1478
- if (oOldHash) {
1479
- sOldFullAppId = `application-${oOldHash.semanticObject}-${oOldHash.action}`;
1480
- oOldAppStorageEntry = Storage.get(sOldFullAppId);
1395
+ // todo: [FLPCOREANDUX-10024] GETTER of currentApplication
1396
+ if (typeof sOldShellHash === "string") {
1397
+ const sOldAppId = UrlParsing.getBasicHash(sOldShellHash);
1398
+ if (sOldAppId) {
1399
+ sOldStorageAppId = `application-${sOldAppId}`;
1400
+ oOldAppStorageEntry = Storage.get(sOldStorageAppId);
1481
1401
  }
1482
1402
  if (oOldAppStorageEntry) {
1483
1403
  oCurrentAppContainer = oOldAppStorageEntry.container;
1484
1404
  } else {
1485
- sCurrentPageId = oViewPortContainer.getCurrentCenterPage ? oViewPortContainer.getCurrentCenterPage() : undefined;
1405
+ sCurrentPageId = oViewPortContainer?.getCurrentCenterPage();
1486
1406
  if (sCurrentPageId) {
1487
1407
  oCurrentAppContainer = Element.getElementById(sCurrentPageId);
1488
1408
  }
@@ -1493,115 +1413,70 @@ sap.ui.define([
1493
1413
  // 1. the application is running in a stateful container
1494
1414
  // 2. this is a legacy keep alive app, and we navigate back (this in order to return the container to the pool
1495
1415
  // of containers to it can be used again for the upcoming opened app)
1416
+ // todo: [FLPCOREANDUX-10024] DELETES more iframe
1496
1417
  bReuseStatefulContainer = BlueBoxHandler.isStatefulContainer(oCurrentAppContainer);
1497
- const bSourceIsKeepAliveFromPool = BlueBoxHandler.isStatefulContainerInKeepAlivePool(oCurrentAppContainer) && oCurrentAppContainer.getCurrentAppId?.().length > 0;
1418
+ const bSourceIsKeepAliveFromPool = BlueBoxHandler.isStatefulContainerInKeepAlivePool(oCurrentAppContainer) && !!oCurrentAppContainer.getCurrentAppId();
1498
1419
  if (bReuseStatefulContainer || bSourceIsKeepAliveFromPool) {
1499
- await this.handleExitApplication(sOldFullAppId, oCurrentAppContainer, undefined, undefined, false, false);
1420
+ await this._handleExitApplication(oCurrentAppContainer, false, false);
1500
1421
  if (oCurrentAppContainer === oTargetAppContainer) {
1501
1422
  bNavigationInSameStatefulContainer = true;
1502
1423
  }
1503
1424
  }
1504
1425
 
1505
1426
  //now, we can open the new application
1506
- const bIsInCache = this.isAppOfTypeCached(sFullAppId, bIsAppOfTypeCachable, oKeepAliveMode) || this.isCachedEnabledAsAppParameter(oShellHash, oTarget, oKeepAliveMode);
1507
- //set the default full width value
1508
- const sAppType = this.calculateAppType(oTarget);
1509
- const bDefaultFullWidth = ApplicationType.getDefaultFullWidthSetting(sAppType);
1510
-
1511
- oInnerControl = BlueBoxHandler.getBlueBoxByUrl(oTarget.url);
1512
- bReuseStatefulContainer = BlueBoxHandler.isStatefulContainer(oInnerControl);
1427
+ const sKeepAliveMode = this._calculateKeepAliveMode(sStorageAppId, oResolvedHashFragment, oParsedShellHash);
1428
+ const bShouldBeCached = !!sKeepAliveMode;
1513
1429
 
1430
+ oApplicationContainer = BlueBoxHandler.getBlueBoxByUrl(oResolvedHashFragment.url);
1431
+ bReuseStatefulContainer = BlueBoxHandler.isStatefulContainer(oApplicationContainer);
1432
+ // todo: [FLPCOREANDUX-10024] GETTER of innerControl for keep alive / stateful
1514
1433
  if (!bReuseStatefulContainer) {
1515
- // only clear oInnerControl in case it is not a navigation from an application to the same application
1516
- if (oCurrentApplication && sFullAppId !== oCurrentApplication.appId) {
1517
- oInnerControl = undefined;
1434
+ // only clear oApplicationContainer in case it is not a navigation from an application to the same application
1435
+ if (oCurrentApplication && sStorageAppId !== oCurrentApplication.appId) {
1436
+ oApplicationContainer = undefined;
1518
1437
  }
1519
- oCachedEntry = Storage.get(`application${sAppId}`);
1520
1438
 
1521
- if (oCachedEntry) {
1522
- oInnerControl = oCachedEntry.container;
1523
- if (!bReuseStatefulContainer && bIsInCache && oInnerControl !== undefined) {
1524
- bKeptAliveApp = true;
1525
- }
1526
- }
1527
- }
1439
+ oCachedEntry = Storage.get(sStorageAppId);
1440
+ oApplicationContainer = oCachedEntry?.container;
1528
1441
 
1529
- let bFullWidth;
1530
- const bFullWidthCapability = oTarget?.appCapabilities?.fullWidth;
1531
- const oMetadata = AppConfiguration.getMetadata(oTarget);
1532
- //Here there's a double check for the fullwidth - once as a type of boolean and one as a string.
1533
- //This is because we found that developers configured this variable in the manifest also as a string,
1534
- //so the checks of the oMetadata and the oTarget are to avoid regression with the use of this field.
1535
- if (bDefaultFullWidth) {
1536
- if (oTarget.fullWidth === false || oTarget.fullWidth === "false" ||
1537
- oMetadata.fullWidth === false || oMetadata.fullWidth === "false" || bFullWidthCapability === false) {
1538
- bFullWidth = false;
1442
+ if (oApplicationContainer && bShouldBeCached) {
1443
+ bKeptAliveApp = true;
1539
1444
  }
1540
- } else if (oTarget.fullWidth || oTarget.fullWidth === "true" ||
1541
- oMetadata.fullWidth || oMetadata.fullWidth === "true") {
1542
- bFullWidth = true;
1543
- }
1544
-
1545
- if (bFullWidth === undefined) {
1546
- bFullWidth = bDefaultFullWidth;
1547
1445
  }
1548
1446
 
1447
+ // todo: [FLPCOREANDUX-10024] CREATE / SETTER of currentApplication
1549
1448
  if (bReuseStatefulContainer) {
1550
- if (!oInnerControl) {
1551
- oInnerControl = fnWrapper(
1552
- sIntent,
1553
- oMetadata,
1554
- oShellHash,
1555
- oTarget,
1556
- sAppId,
1557
- bFullWidth,
1558
- sFixedShellHash
1559
- );
1560
- if (this.isAppInCache(oInnerControl.getId())) {
1561
- oCurrentApplication = Storage.get(oInnerControl.getId());
1449
+ if (!oApplicationContainer) {
1450
+ oApplicationContainer = await this._createApplicationContainer(sAppId, oParsedShellHash, oResolvedHashFragment);
1451
+
1452
+ // todo: [FLPCOREANDUX-10024] the following should be obsolete
1453
+ const oStorageEntry = Storage.get(oApplicationContainer.getId());
1454
+ if (oStorageEntry) {
1455
+ oCurrentApplication = oStorageEntry;
1562
1456
  }
1563
- this.navTo(oInnerControl.getId());
1564
- bIsInitial = true;
1457
+
1458
+ bNewlyCreatedApplicationContainer = true;
1565
1459
  }
1566
- } else if (BlueBoxHandler.getStatefulContainerType(oTarget.url, true) !== BlueBoxHandler.STATEFUL_TYPES.GUI_V1 && oInnerControl && !bIsInCache) {
1567
- //this case this controller cant be reused and we need it to be embed, so delete it.
1568
- await this.destroyApplication(oInnerControl.getId(), oInnerControl);
1460
+ } else if (oApplicationContainer && !bShouldBeCached && BlueBoxHandler.getStatefulContainerType(oResolvedHashFragment.url, true) !== BlueBoxHandler.STATEFUL_TYPES.GUI_V1) {
1461
+ //this case this controller can't be reused and we need it to be embed, so delete it.
1462
+ await this._destroyApplication(oApplicationContainer.getId(), oApplicationContainer);
1569
1463
 
1570
1464
  // The immediately following method call internally calls
1571
- // `this.oViewPortContainer.addCenterViewPort(oAppContainer)`
1465
+ // `this.oViewPortContainer.addCenterViewPort(oApplicationContainer)`
1572
1466
  // when Gui V1 Stateful Container is true, and in that case
1573
- // `oInnerControl` will be the component control of an existing session.
1574
- oInnerControl = fnWrapper(
1575
- sIntent,
1576
- oMetadata,
1577
- oShellHash,
1578
- oTarget,
1579
- sAppId,
1580
- bFullWidth,
1581
- sFixedShellHash
1582
- );
1583
- } else if (!oInnerControl) {
1467
+ // `oApplicationContainer` will be the component control of an existing session.
1468
+ oApplicationContainer = await this._createApplicationContainer(sAppId, oParsedShellHash, oResolvedHashFragment);
1469
+ } else if (!oApplicationContainer) {
1584
1470
  // The immediately following method call internally calls
1585
- // `this.oViewPortContainer.addCenterViewPort(oAppContainer)`
1471
+ // `this.oViewPortContainer.addCenterViewPort(oApplicationContainer)`
1586
1472
  // when Gui V1 Stateful Container is true, and in that case
1587
- // `oInnerControl` will be the component control of an existing session.
1588
- oInnerControl = fnWrapper(
1589
- sIntent,
1590
- oMetadata,
1591
- oShellHash,
1592
- oTarget,
1593
- sAppId,
1594
- bFullWidth,
1595
- sFixedShellHash
1596
- );
1473
+ // `oApplicationContainer` will be the component control of an existing session.
1474
+ oApplicationContainer = await this._createApplicationContainer(sAppId, oParsedShellHash, oResolvedHashFragment);
1597
1475
 
1598
1476
  //if we got an iframe from cache, simulate stateful container
1599
1477
  //open that should happen later here
1600
- // if (oInnerControl && oInnerControl.getProperty && oInnerControl.getProperty("fetchedFromCache") === true) {
1601
- // InnerControl.getProperty("fetchedFromIframeCache", false, true);
1602
- // }
1603
- if (oInnerControl?.getIsFetchedFromCache?.() && oInnerControl.getStatefulType) {
1604
- if (oInnerControl.getStatefulType() === -BlueBoxHandler.STATEFUL_TYPES.GUI_V1) {
1478
+ if (oApplicationContainer.getIsFetchedFromCache()) {
1479
+ if (oApplicationContainer.getStatefulType() === -BlueBoxHandler.STATEFUL_TYPES.GUI_V1) {
1605
1480
  bReturnedFromKeepAlivePoolGuiV1 = true;
1606
1481
  } else {
1607
1482
  bReuseStatefulContainer = true;
@@ -1610,22 +1485,24 @@ sap.ui.define([
1610
1485
  }
1611
1486
  }
1612
1487
 
1613
- if (oInnerControl?.getDeffedControlCreation) {
1614
- await ushellUtils.promisify(oInnerControl.getDeffedControlCreation());
1615
- }
1488
+ // todo: [FLPCOREANDUX-10024] rework empty applicationContainer case
1489
+ // fallback?
1490
+
1491
+ await ushellUtils.promisify(oApplicationContainer.getDeffedControlCreation());
1616
1492
 
1617
1493
  //here, we simply show (turning to visible) the container of the new opened application in case it is not stateful container
1618
1494
  //and not old gui v1 stateful
1619
- if (oInnerControl.getStatefulType && oInnerControl.getStatefulType() !== BlueBoxHandler.STATEFUL_TYPES.GUI_V1 && !bReuseStatefulContainer) {
1495
+ if (oApplicationContainer.getStatefulType() !== BlueBoxHandler.STATEFUL_TYPES.GUI_V1 && !bReuseStatefulContainer) {
1620
1496
  if (bKeptAliveApp) {
1621
- EventBus.getInstance().publish("launchpad", "appOpening", oTarget);
1497
+ EventBus.getInstance().publish("launchpad", "appOpening", oResolvedHashFragment);
1622
1498
  }
1623
- if (this.isAppInCache(oInnerControl.getId())) {
1624
- oCurrentApplication = Storage.get(oInnerControl.getId());
1499
+ const oStorageEntry = Storage.get(oApplicationContainer.getId());
1500
+ if (oStorageEntry) {
1501
+ oCurrentApplication = oStorageEntry;
1625
1502
  }
1626
- this.navTo(oInnerControl.getId());
1503
+
1627
1504
  if (bKeptAliveApp) {
1628
- EventBus.getInstance().publish("sap.ushell", "appOpened", oTarget);
1505
+ EventBus.getInstance().publish("sap.ushell", "appOpened", oResolvedHashFragment);
1629
1506
  }
1630
1507
  }
1631
1508
 
@@ -1636,50 +1513,79 @@ sap.ui.define([
1636
1513
  // so this makes sure the container is active before sending the event.
1637
1514
  // For WD applications, the application is active only after the application is created.
1638
1515
  // So it is not navigated twice.
1639
- if (oInnerControl.getApplicationType() === ApplicationType.TR.type) {
1640
- this.activeContainer(oInnerControl);
1516
+ if (oApplicationContainer.getApplicationType() === ApplicationType.TR.type) {
1517
+ this._activeContainer(oApplicationContainer);
1518
+ }
1519
+
1520
+ const oStorageEntry = Storage.get(sStorageAppId);
1521
+ if (oStorageEntry) {
1522
+ AppInfoParameters.restore(oStorageEntry);
1523
+ } else {
1524
+ AppInfoParameters.flush();
1641
1525
  }
1526
+
1527
+
1642
1528
  //here, we create the application in case this is a stateful container (meaning, using the existing iframe)
1643
1529
  if (bReuseStatefulContainer) {
1644
1530
  //for scube - make sure the container is active before we open the app
1645
1531
  //to allow post messages form the iframe to flp that are sent
1646
1532
  //as part of the target resolution process
1647
- if (oTarget.appCapabilities?.appFrameworkId === "UI5") {
1648
- oInnerControl.setProperty("active", true, true);
1533
+ if (oResolvedHashFragment.appCapabilities?.appFrameworkId === "UI5") {
1534
+ oApplicationContainer.setProperty("active", true, true);
1649
1535
  }
1650
1536
  // eslint-disable-next-line max-len
1651
- await this.handleOpenStateful(bIsInitial, bIsInCache, `application${sAppId}`, oInnerControl, oTarget, sFixedShellHash, oKeepAliveMode, bNavigationInSameStatefulContainer, bReturnedFromKeepAlivePoolFLPV2);
1652
- } else if (oInnerControl.getStatefulType?.() === BlueBoxHandler.STATEFUL_TYPES.GUI_V1 || bReturnedFromKeepAlivePoolGuiV1) {
1537
+ await this._handleOpenStateful(bNewlyCreatedApplicationContainer, bShouldBeCached, sStorageAppId, oApplicationContainer, oResolvedHashFragment, oParsedShellHash, sKeepAliveMode, bNavigationInSameStatefulContainer, bReturnedFromKeepAlivePoolFLPV2);
1538
+
1539
+ } else if (oApplicationContainer.getStatefulType() === BlueBoxHandler.STATEFUL_TYPES.GUI_V1 || bReturnedFromKeepAlivePoolGuiV1) {
1653
1540
  //here, we create the application in case this is old gui v1 stateful
1654
- await WebGUIStatefulHandler.guiStatefulCreateApp(this, oInnerControl, oTarget);
1541
+ await WebGUIStatefulHandler.guiStatefulCreateApp(this, oApplicationContainer, oResolvedHashFragment);
1655
1542
  }
1656
1543
 
1657
1544
  //for case of stateful container or gui v1 stateful, show the application view (make it visible)
1658
1545
  ushellUtils.setPerformanceMark("FLP -- centerViewPort");
1659
- if (oInnerControl.getApplicationType() !== ApplicationType.TR.type) {
1546
+ if (oApplicationContainer.getApplicationType() !== ApplicationType.TR.type) {
1660
1547
  // Activate container before showing it (start reacting to postMessage calls)
1661
- this.activeContainer(oInnerControl);
1548
+ this._activeContainer(oApplicationContainer);
1662
1549
  }
1663
1550
 
1664
1551
  /*
1665
- * Workaround:
1666
- * The oCurrentApplication object does not reflect the currently opened application.
1667
- * This leads to store/restore calls on the wrong application.
1668
- * Create application that is not persisted and not cashed as a fallback.
1669
- *
1670
- * This issue occurs for iframe applications reusing the iframe.
1671
- */
1672
- if (oCurrentApplication.appId !== sFullAppId) {
1552
+ * Workaround:
1553
+ * The oCurrentApplication object does not reflect the currently opened application.
1554
+ * This leads to store/restore calls on the wrong application.
1555
+ * Create application that is not persisted and not cashed as a fallback.
1556
+ *
1557
+ * This issue occurs for iframe applications reusing the iframe.
1558
+ */
1559
+ if (oCurrentApplication.appId !== sStorageAppId) {
1673
1560
  oCurrentApplication = {
1674
- appId: sFullAppId,
1561
+ appId: sStorageAppId,
1675
1562
  stt: "loading",
1676
- container: oInnerControl,
1677
- meta: AppConfiguration.getMetadata(oTarget),
1563
+ container: oApplicationContainer,
1564
+ meta: AppConfiguration.getMetadata(oResolvedHashFragment),
1678
1565
  app: undefined
1679
1566
  };
1680
1567
  }
1681
1568
  };
1682
1569
 
1570
+ /**
1571
+ */
1572
+ this.navToCurrentApp = function () {
1573
+ const oApplicationContainer = this.getCurrentApplication().container;
1574
+ // todo: [FLPCOREANDUX-10024] maybe switch to 'this.getCurrentApplication().appId' instead
1575
+ this._navTo(oApplicationContainer.getId());
1576
+
1577
+ // todo: [FLPCOREANDUX-10024]
1578
+ // - Move styles into control? or at least out of here
1579
+ // - Is this even needed? This doesn't seem to trigger the onAfterNavigate as indicated by the following comment.
1580
+ //Added this because in cases when navigating to the same id (can happen when stateful container, I need the on onAfterNavigate)
1581
+ //This must only be done after the _navTo as the ViewPortContainer's navTo function relies on the state of those classes.
1582
+ if (oApplicationContainer.hasStyleClass("sapUShellApplicationContainerShiftedIframe")) {
1583
+ oApplicationContainer.toggleStyleClass("sapUShellApplicationContainerIframeHidden", false);
1584
+ } else {
1585
+ oApplicationContainer.toggleStyleClass("hidden", false);
1586
+ }
1587
+ };
1588
+
1683
1589
  /**
1684
1590
  * New app was created and we now have to switch the state
1685
1591
  * @param {string} sLaunchpadState
@@ -1710,7 +1616,8 @@ sap.ui.define([
1710
1616
  StateManager.switchState(sLaunchpadState, sShellModeOverride);
1711
1617
 
1712
1618
  // Restore state if it already exists
1713
- const oToStorageEntry = Storage.get(`application${sAppId}`);
1619
+ const sToStorageAppId = `application-${sAppId}`;
1620
+ const oToStorageEntry = Storage.get(sToStorageAppId);
1714
1621
  if (oToStorageEntry) {
1715
1622
  KeepAlive.restore(oToStorageEntry);
1716
1623
  } else {
@@ -1729,25 +1636,256 @@ sap.ui.define([
1729
1636
  };
1730
1637
 
1731
1638
  /**
1732
- * @param {string} sHandlers
1733
- * @param {string} sType
1639
+ * @returns {boolean} Whether the floating container is docked.
1640
+ */
1641
+ this._isFloatingContainerDocked = function () {
1642
+ const bDocked = ShellModel.getModel().getProperty("/floatingContainer/state").includes("docked");
1643
+ const bVisible = ShellModel.getModel().getProperty("/floatingContainer/visible");
1644
+ return bDocked && bVisible;
1645
+ };
1646
+
1647
+ /**
1734
1648
  */
1735
- this.registerIframeCommunicationHandler = function (sHandlers, sType) {
1736
- oGlobalIframeCommunicationHandlers[sType] = sHandlers;
1649
+ this._sendFocusBackToShell = function () {
1650
+ if (!Device.system.desktop) {
1651
+ return;
1652
+ }
1653
+
1654
+ sap.ui.require(["sap/ushell/renderer/AccessKeysHandler"], (AccessKeysHandler) => {
1655
+ const sCurrentLaunchpadState = StateManager.getLaunchpadState();
1656
+ const bDefaultShellMode = StateManager.getShellMode() === ShellMode.Default;
1657
+ const oShellAppTitle = Element.getElementById("shellAppTitle");
1658
+
1659
+ if (oShellAppTitle && sCurrentLaunchpadState === LaunchpadState.App && bDefaultShellMode) {
1660
+ const oShellAppTitleDomRef = oShellAppTitle.getFocusDomRef();
1661
+ if (oShellAppTitleDomRef) {
1662
+ AccessKeysHandler.sendFocusBackToShell(oShellAppTitleDomRef.getAttribute("id"));
1663
+ }
1664
+ }
1665
+ });
1737
1666
  };
1738
1667
 
1739
1668
  /**
1740
- * @param {boolean} bIsBackNavigationChangedValue
1669
+ * @param {object} oResolvedHashFragment
1741
1670
  */
1742
- this.setBackNavigationChanged = function (bIsBackNavigationChangedValue) {
1743
- isBackNavigationChanged = bIsBackNavigationChangedValue;
1671
+ this._announceAppOpening = function (oResolvedHashFragment) {
1672
+ //Screen reader: "Loading Complete"
1673
+ window.setTimeout(() => {
1674
+ window.setTimeout(() => {
1675
+ const oAccessibilityHelperLoadingComplete = document.getElementById("sapUshellLoadingAccessibilityHelper-loadingComplete");
1676
+
1677
+ if (oAccessibilityHelperLoadingComplete) {
1678
+ oAccessibilityHelperLoadingComplete.setAttribute("aria-live", "polite");
1679
+ oAccessibilityHelperLoadingComplete.innerHTML = ushellResources.i18n.getText("loadingComplete");
1680
+ window.setTimeout(() => {
1681
+ oAccessibilityHelperLoadingComplete.setAttribute("aria-live", "off");
1682
+ oAccessibilityHelperLoadingComplete.innerHTML = "";
1683
+ }, 0);
1684
+ }
1685
+ }, 600);
1686
+
1687
+ EventBus.getInstance().publish("launchpad", "appOpening", oResolvedHashFragment);
1688
+ Log.info("app is being opened");
1689
+ }, 0);
1744
1690
  };
1745
1691
 
1746
1692
  /**
1747
- * @returns {boolean} Whether the back navigation was changed.
1693
+ * @param {string} sAppId
1694
+ * @param {object} oParsedShellHash
1695
+ * @param {object} oResolvedHashFragment
1696
+ * @param {string} sShellHash
1697
+ * @returns {object} The app container.
1698
+ */
1699
+ this._createApplicationContainer = async function (sAppId, oParsedShellHash, oResolvedHashFragment) {
1700
+ const oMetadata = AppConfiguration.getMetadata(oResolvedHashFragment);
1701
+ const bFullWidth = this._isFullWidth(oResolvedHashFragment);
1702
+
1703
+ /*
1704
+ * The external navigation mode in the resolution result is calculated
1705
+ * statically, and indicates a future state. It currently answers the
1706
+ * question: "is the application going to be opened explace?".
1707
+ *
1708
+ * The target navigation mode, instead, answers the question: "was
1709
+ * the application opened explace?".
1710
+ *
1711
+ * We need to have this logic, because embedded applications do not
1712
+ * check the coldstart condition.
1713
+ */
1714
+ oResolvedHashFragment.targetNavigationMode = ushellUtils.isColdStart() ? "explace" : "inplace";
1715
+ oResolvedHashFragment.shellUIService = oGlobalShellUIService.getInterface();
1716
+
1717
+ // send focus back to shell for new ApplicationContainers
1718
+ this._sendFocusBackToShell();
1719
+
1720
+ this._announceAppOpening(oResolvedHashFragment);
1721
+
1722
+ await this._openApp(sAppId, oResolvedHashFragment, oParsedShellHash);
1723
+ const oApplicationContainer = oCurrentApplication.container;
1724
+
1725
+ const bContainerFromCachePool = oApplicationContainer.getIsFetchedFromCache();
1726
+
1727
+ if (!bContainerFromCachePool) {
1728
+ this._publishNavigationStateEvents(oApplicationContainer, oResolvedHashFragment, this.onAppAfterRendering.bind(this, oResolvedHashFragment));
1729
+
1730
+ if (ushellUtils.isSAPLegacyApplicationType(oApplicationContainer.getApplicationType(), oApplicationContainer.getFrameworkId())) {
1731
+ oApplicationContainer.addStyleClass("sapUShellApplicationContainerShiftedIframe");
1732
+ }
1733
+
1734
+ if (!bFullWidth) {
1735
+ oApplicationContainer.addStyleClass("sapUShellApplicationContainerLimitedWidth");
1736
+ }
1737
+
1738
+ // todo: [FLPCOREANDUX-10024] clarify whether this should be reactive instead of one time only
1739
+ // todo: [FLPCOREANDUX-10024] move this block to ShellController
1740
+ if (this._isFloatingContainerDocked() && window.matchMedia("(min-width: 106.4rem)").matches) {
1741
+ oApplicationContainer.addStyleClass("sapUShellDockingContainer");
1742
+ oApplicationContainer.removeStyleClass("sapUShellApplicationContainerLimitedWidth");
1743
+ } else if (this._isFloatingContainerDocked()) {
1744
+ oApplicationContainer.removeStyleClass("sapUShellApplicationContainerLimitedWidth");
1745
+ }
1746
+
1747
+ oApplicationContainer.toggleStyleClass("sapUshellDefaultBackground", !oMetadata.hideLightBackground);
1748
+
1749
+ AppMeta._applyContentDensityByPriority();
1750
+
1751
+ // Add inner control for next request
1752
+ this._addApplicationContainerToViewPort(oApplicationContainer);
1753
+ }
1754
+
1755
+ ushellUtils.setPerformanceMark("FLP - addAppContainer");
1756
+
1757
+ return oApplicationContainer;
1758
+ };
1759
+
1760
+ /**
1761
+ * @param {string} sShellHash
1762
+ * @param {object} oResolvedHashFragment
1763
+ * @param {boolean} bNavigationFromHome
1764
+ * @param {boolean} bNavigationWithInnerAppRoute
1765
+ */
1766
+ this.handleBeforeCreateApp = async function (sShellHash, oResolvedHashFragment, bNavigationFromHome, bNavigationWithInnerAppRoute) {
1767
+ const sIntent = UrlParsing.getBasicHash(sShellHash);
1768
+ const bComponentLoaded = !!oResolvedHashFragment?.componentHandle;
1769
+ // for SAPUI5 apps, the application type is still "URL" due to backwards compatibility, but the
1770
+ // NavTargetResolutionInternal service already extracts the component name, so this can directly be used as indicator
1771
+ const sTargetUi5ComponentName = oResolvedHashFragment?.ui5ComponentName;
1772
+
1773
+ const oInMemoryApplicationInstance = this._getInMemoryInstance(sIntent, sShellHash, bNavigationFromHome, bNavigationWithInnerAppRoute);
1774
+
1775
+ if (oInMemoryApplicationInstance.isInstanceSupported) {
1776
+ // no destroy required
1777
+
1778
+ } else if (bComponentLoaded || !sTargetUi5ComponentName) {
1779
+ if ((
1780
+ oResolvedHashFragment.applicationType === "URL"
1781
+ || ushellUtils.isSAPLegacyApplicationType(oResolvedHashFragment.applicationType)
1782
+ )
1783
+ && oInMemoryApplicationInstance.isInstanceSupported === false
1784
+ && oInMemoryApplicationInstance.appId
1785
+ ) {
1786
+ await this._destroyApplication(oInMemoryApplicationInstance.appId, oInMemoryApplicationInstance.container);
1787
+ }
1788
+
1789
+ } else { // UI5 Application
1790
+ await this._destroyApplication(oInMemoryApplicationInstance.appId, oInMemoryApplicationInstance.container);
1791
+ const oApplicationContainer = this._getApplicationContainerFromViewPort(sIntent);
1792
+
1793
+ if (oApplicationContainer) {
1794
+ this._removeApplicationContainerFromViewPort(oApplicationContainer.getId());
1795
+ oApplicationContainer.destroy();
1796
+ }
1797
+
1798
+ // close all keep alive apps with the same component name
1799
+ await this._closeKeepAliveApps((oStorageEntry) => oStorageEntry.ui5ComponentName === oResolvedHashFragment.ui5ComponentName);
1800
+ }
1801
+ };
1802
+
1803
+ /**
1804
+ * @param {string} sShellHash
1805
+ * @param {object} oParsedShellHash
1806
+ * @param {object} oResolvedHashFragment
1807
+ * @param {boolean} bNavigationFromHome
1808
+ * @param {boolean} bNavigationWithInnerAppRoute
1809
+ */
1810
+ this.handleCreateApp = async function (sShellHash, oParsedShellHash, oResolvedHashFragment, bNavigationFromHome, bNavigationWithInnerAppRoute) {
1811
+ const sIntent = UrlParsing.getBasicHash(sShellHash);
1812
+ const bComponentLoaded = !!oResolvedHashFragment?.componentHandle;
1813
+ // for SAPUI5 apps, the application type is still "URL" due to backwards compatibility, but the
1814
+ // NavTargetResolutionInternal service already extracts the component name, so this can directly be used as indicator
1815
+ const sTargetUi5ComponentName = oResolvedHashFragment?.ui5ComponentName;
1816
+ const bIsUI5App = !!sTargetUi5ComponentName;
1817
+ const oInMemoryApplicationInstance = this._getInMemoryInstance(sIntent, sShellHash, bNavigationFromHome, bNavigationWithInnerAppRoute);
1818
+
1819
+ if (bIsUI5App && !bComponentLoaded && !oInMemoryApplicationInstance.isInstanceSupported) { // UI5 Application
1820
+ AppConfiguration.setApplicationInInitMode();
1821
+
1822
+ /*
1823
+ * normal application:
1824
+ * fire the _prior.newUI5ComponentInstantion event before creating the new component instance, so that
1825
+ * the ApplicationContainer can stop the router of the current app (avoid inner-app hash change notifications)
1826
+ * NOTE: this dependency to the ApplicationContainer is not nice, but we need a fast fix now; we should refactor
1827
+ * the ApplicationContainer code, because most of the logic has to be done by the shell controller;
1828
+ * maybe rather introduce a utility module
1829
+ */
1830
+ EventBus.getInstance().publish("ApplicationContainer", "_prior.newUI5ComponentInstantion",
1831
+ { name: sTargetUi5ComponentName }
1832
+ );
1833
+
1834
+ // load ui5 component via shell service; core-ext-light will be loaded as part of the asyncHints
1835
+ await Container.getServiceAsync("Ui5ComponentLoader");
1836
+
1837
+ /*
1838
+ * FIXME: It would be better to call a function that simply
1839
+ * and intentionally loads the dependencies of the UI5
1840
+ * application, rather than creating a component and expecting
1841
+ * the dependencies to be loaded as a side effect.
1842
+ * Moreover, the comment reads "load ui5 component via shell service"
1843
+ * however that is 'not needed' since the loaded component
1844
+ * is not used. We should evaluate the possible performance
1845
+ * hit taken due to this implicit means to an end.
1846
+ */
1847
+
1848
+ /*
1849
+ * return value is unused.
1850
+ * This is because oResolvedHashFragment contains the component handle already.
1851
+ * See the preceding note in AppLifeCycle.createComponent.
1852
+ */
1853
+ await Application.createComponent(oResolvedHashFragment, oParsedShellHash);
1854
+ }
1855
+ };
1856
+
1857
+ /**
1858
+ *
1859
+ * @param {sap.ui.core.Component} oApplication
1860
+ */
1861
+ this.onAppAfterRendering = function (oApplication) {
1862
+ // wrapped in setTimeout since "publish" is not async
1863
+ window.setTimeout(() => {
1864
+ EventBus.getInstance().publish("sap.ushell", "appOpened", oApplication);
1865
+ Log.info("app was opened");
1866
+ }, 0);
1867
+
1868
+ // publish the event externally
1869
+ // TODO: cloned, frozen object!
1870
+ const oAppOpenedEventData = this._publicEventDataFromResolutionResult(oApplication);
1871
+
1872
+ // Event is emitted internally (EventHub) _and_ externally (for compatibility reasons)
1873
+ EventHub.emit("AppRendered", oAppOpenedEventData, true);
1874
+ RendererUtils.publishExternalEvent("appOpened", oAppOpenedEventData);
1875
+ ushellUtils.setPerformanceMark("FLP.appOpened");
1876
+
1877
+ const sIcon = AppMeta.getAppIcon();
1878
+ StateManager.updateCurrentState("application.icon", Operation.Set, sIcon);
1879
+ };
1880
+
1881
+ /**
1882
+ * Only for testing
1883
+ * @param {sap.ui.core.Control} oNewViewPortContainer
1884
+ *
1885
+ * @private
1748
1886
  */
1749
- this.getBackNavigationChanged = function () {
1750
- return isBackNavigationChanged;
1887
+ this.setViewPortContainer = function (oNewViewPortContainer) {
1888
+ oViewPortContainer = oNewViewPortContainer;
1751
1889
  };
1752
1890
  }
1753
1891