@sapui5/sap.fe.core 1.99.0 → 1.101.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.
- package/package.json +6 -4
- package/src/sap/fe/core/.library +2 -3
- package/src/sap/fe/core/AnnotationHelper.js +43 -92
- package/src/sap/fe/core/AnnotationHelper.ts +43 -107
- package/src/sap/fe/core/AppComponent.js +381 -399
- package/src/sap/fe/core/AppComponent.ts +397 -0
- package/src/sap/fe/core/AppStateHandler.js +131 -162
- package/src/sap/fe/core/AppStateHandler.ts +2 -2
- package/src/sap/fe/core/BaseController.js +82 -58
- package/src/sap/fe/core/BaseController.ts +67 -0
- package/src/sap/fe/core/CommonUtils.js +179 -31
- package/src/sap/fe/core/CommonUtils.ts +295 -125
- package/src/sap/fe/core/ExtensionAPI.js +279 -274
- package/src/sap/fe/core/ExtensionAPI.ts +242 -0
- package/src/sap/fe/core/PageController.js +158 -29
- package/src/sap/fe/core/PageController.ts +65 -37
- package/src/sap/fe/core/RouterProxy.js +700 -750
- package/src/sap/fe/core/RouterProxy.ts +47 -31
- package/src/sap/fe/core/Synchronization.js +21 -31
- package/src/sap/fe/core/TemplateComponent.js +193 -118
- package/src/sap/fe/core/TemplateComponent.ts +104 -109
- package/src/sap/fe/core/TemplateModel.js +24 -44
- package/src/sap/fe/core/TemplateModel.ts +3 -3
- package/src/sap/fe/core/TransactionHelper.js +1368 -1369
- package/src/sap/fe/core/TransactionHelper.ts +201 -171
- package/src/sap/fe/core/actions/collaboration/ActivitySync.js +406 -0
- package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +362 -0
- package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +146 -0
- package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +129 -0
- package/src/sap/fe/core/actions/collaboration/Manage.js +264 -0
- package/src/sap/fe/core/actions/collaboration/Manage.ts +246 -0
- package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +100 -0
- package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
- package/src/sap/fe/core/actions/draft.js +324 -220
- package/src/sap/fe/core/actions/draft.ts +209 -133
- package/src/sap/fe/core/actions/messageHandling.js +79 -48
- package/src/sap/fe/core/actions/messageHandling.ts +113 -83
- package/src/sap/fe/core/actions/operations.js +37 -18
- package/src/sap/fe/core/actions/operations.ts +51 -20
- package/src/sap/fe/core/actions/sticky.js +17 -4
- package/src/sap/fe/core/actions/sticky.ts +21 -4
- package/src/sap/fe/core/buildingBlocks/AttributeModel.js +60 -0
- package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +37 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +165 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +178 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +707 -0
- package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +628 -0
- package/src/sap/fe/core/buildingBlocks/TraceInfo.js +436 -0
- package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +431 -0
- package/src/sap/fe/core/controllerextensions/EditFlow.js +1854 -1669
- package/src/sap/fe/core/controllerextensions/EditFlow.ts +1792 -0
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +79 -54
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +60 -0
- package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +716 -779
- package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +785 -0
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +796 -816
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +810 -0
- package/src/sap/fe/core/controllerextensions/InternalRouting.js +1056 -1005
- package/src/sap/fe/core/controllerextensions/InternalRouting.ts +1001 -0
- package/src/sap/fe/core/controllerextensions/KPIManagement.js +498 -532
- package/src/sap/fe/core/controllerextensions/KPIManagement.ts +13 -12
- package/src/sap/fe/core/controllerextensions/MassEdit.js +141 -169
- package/src/sap/fe/core/controllerextensions/MassEdit.ts +155 -0
- package/src/sap/fe/core/controllerextensions/MessageHandler.js +221 -244
- package/src/sap/fe/core/controllerextensions/MessageHandler.ts +215 -0
- package/src/sap/fe/core/controllerextensions/PageReady.js +312 -345
- package/src/sap/fe/core/controllerextensions/PageReady.ts +57 -53
- package/src/sap/fe/core/controllerextensions/Paginator.js +188 -175
- package/src/sap/fe/core/controllerextensions/Paginator.ts +169 -0
- package/src/sap/fe/core/controllerextensions/Placeholder.js +157 -149
- package/src/sap/fe/core/controllerextensions/Placeholder.ts +149 -0
- package/src/sap/fe/core/controllerextensions/Routing.js +144 -125
- package/src/sap/fe/core/controllerextensions/Routing.ts +131 -0
- package/src/sap/fe/core/controllerextensions/RoutingListener.js +7 -6
- package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
- package/src/sap/fe/core/controllerextensions/Share.js +230 -268
- package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
- package/src/sap/fe/core/controllerextensions/SideEffects.js +603 -644
- package/src/sap/fe/core/controllerextensions/SideEffects.ts +68 -68
- package/src/sap/fe/core/controllerextensions/ViewState.js +774 -806
- package/src/sap/fe/core/controllerextensions/ViewState.ts +796 -0
- package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -2
- package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
- package/src/sap/fe/core/controls/Any.js +28 -0
- package/src/sap/fe/core/controls/Any.ts +30 -0
- package/src/sap/fe/core/controls/CommandExecution.js +92 -68
- package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
- package/src/sap/fe/core/controls/ConditionalWrapper.js +165 -79
- package/src/sap/fe/core/controls/ConditionalWrapper.ts +74 -0
- package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +366 -0
- package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +278 -0
- package/src/sap/fe/core/controls/CustomQuickViewPage.js +167 -125
- package/src/sap/fe/core/controls/CustomQuickViewPage.ts +116 -0
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +44 -5
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +163 -122
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +155 -0
- package/src/sap/fe/core/controls/FieldWrapper.js +212 -141
- package/src/sap/fe/core/controls/FieldWrapper.ts +104 -0
- package/src/sap/fe/core/controls/FileWrapper.js +313 -0
- package/src/sap/fe/core/controls/FileWrapper.ts +169 -0
- package/src/sap/fe/core/controls/FilterBar.js +197 -159
- package/src/sap/fe/core/controls/FilterBar.ts +148 -0
- package/src/sap/fe/core/controls/FormElementWrapper.js +100 -39
- package/src/sap/fe/core/controls/FormElementWrapper.ts +37 -0
- package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +37 -42
- package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
- package/src/sap/fe/core/controls/filterbar/FilterContainer.js +147 -115
- package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +102 -0
- package/src/sap/fe/core/controls/filterbar/VisualFilter.js +300 -265
- package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +252 -0
- package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +185 -140
- package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
- package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +335 -322
- package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
- package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +37 -42
- package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +75 -74
- package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +71 -0
- package/src/sap/fe/core/converters/ConverterContext.js +348 -379
- package/src/sap/fe/core/converters/ConverterContext.ts +19 -16
- package/src/sap/fe/core/converters/ManifestSettings.js +13 -1
- package/src/sap/fe/core/converters/ManifestSettings.ts +17 -2
- package/src/sap/fe/core/converters/ManifestWrapper.js +354 -378
- package/src/sap/fe/core/converters/ManifestWrapper.ts +10 -0
- package/src/sap/fe/core/converters/MetaModelConverter.js +6 -4
- package/src/sap/fe/core/converters/MetaModelConverter.ts +5 -2
- package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
- package/src/sap/fe/core/converters/TemplateConverter.ts +2 -1
- package/src/sap/fe/core/converters/annotations/DataField.js +26 -13
- package/src/sap/fe/core/converters/annotations/DataField.ts +40 -17
- package/src/sap/fe/core/converters/controls/Common/Action.js +10 -10
- package/src/sap/fe/core/converters/controls/Common/Action.ts +20 -19
- package/src/sap/fe/core/converters/controls/Common/Chart.js +8 -8
- package/src/sap/fe/core/converters/controls/Common/Chart.ts +12 -11
- package/src/sap/fe/core/converters/controls/Common/Form.js +6 -6
- package/src/sap/fe/core/converters/controls/Common/Form.ts +7 -3
- package/src/sap/fe/core/converters/controls/Common/KPI.js +1 -1
- package/src/sap/fe/core/converters/controls/Common/KPI.ts +2 -2
- package/src/sap/fe/core/converters/controls/Common/Table.js +326 -86
- package/src/sap/fe/core/converters/controls/Common/Table.ts +384 -167
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +120 -55
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +158 -98
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +206 -223
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +263 -287
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +6 -6
- package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +20 -18
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +5 -2
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +4 -1
- package/src/sap/fe/core/converters/helpers/Aggregation.js +115 -133
- package/src/sap/fe/core/converters/helpers/BindingHelper.js +20 -6
- package/src/sap/fe/core/converters/helpers/BindingHelper.ts +16 -4
- package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +12 -1
- package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +11 -0
- package/src/sap/fe/core/converters/helpers/Key.js +42 -57
- package/src/sap/fe/core/converters/helpers/Key.ts +1 -1
- package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +1 -1
- package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +0 -4
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +51 -27
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +69 -43
- package/src/sap/fe/core/converters/templates/ListReportConverter.js +42 -25
- package/src/sap/fe/core/converters/templates/ListReportConverter.ts +91 -65
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +11 -9
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +8 -8
- package/src/sap/fe/core/designtime/AppComponent.designtime.js +92 -98
- package/src/sap/fe/core/designtime/AppComponent.designtime.ts +91 -0
- package/src/sap/fe/core/formatters/CollaborationFormatter.js +104 -0
- package/src/sap/fe/core/formatters/CollaborationFormatter.ts +60 -0
- package/src/sap/fe/core/formatters/KPIFormatter.js +3 -12
- package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -2
- package/src/sap/fe/core/formatters/TableFormatter.js +53 -2
- package/src/sap/fe/core/formatters/TableFormatter.ts +51 -0
- package/src/sap/fe/core/formatters/ValueFormatter.js +4 -4
- package/src/sap/fe/core/formatters/ValueFormatter.ts +4 -7
- package/src/sap/fe/core/fpm/Component.js +80 -55
- package/src/sap/fe/core/fpm/Component.ts +43 -0
- package/src/sap/fe/core/helpers/AppStartupHelper.js +323 -309
- package/src/sap/fe/core/helpers/AppStartupHelper.ts +363 -337
- package/src/sap/fe/core/helpers/BindingExpression.js +7 -7
- package/src/sap/fe/core/helpers/BindingExpression.ts +7 -7
- package/src/sap/fe/core/helpers/ClassSupport.js +307 -166
- package/src/sap/fe/core/helpers/ClassSupport.ts +348 -155
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +5 -4
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -5
- package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
- package/src/sap/fe/core/helpers/FPMHelper.ts +1 -1
- package/src/sap/fe/core/helpers/MassEditHelper.js +735 -684
- package/src/sap/fe/core/helpers/MassEditHelper.ts +803 -0
- package/src/sap/fe/core/helpers/ModelHelper.js +53 -1
- package/src/sap/fe/core/helpers/ModelHelper.ts +46 -0
- package/src/sap/fe/core/helpers/PasteHelper.js +4 -4
- package/src/sap/fe/core/helpers/PasteHelper.ts +4 -3
- package/src/sap/fe/core/helpers/SemanticDateOperators.js +7 -3
- package/src/sap/fe/core/helpers/SemanticDateOperators.ts +7 -1
- package/src/sap/fe/core/helpers/SemanticKeyHelper.js +1 -1
- package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +1 -1
- package/src/sap/fe/core/helpers/StableIdHelper.js +1 -7
- package/src/sap/fe/core/helpers/StableIdHelper.ts +0 -4
- package/src/sap/fe/core/jsx-runtime/jsx.js +35 -5
- package/src/sap/fe/core/jsx-runtime/jsx.ts +22 -8
- package/src/sap/fe/core/library.js +425 -451
- package/src/sap/fe/core/library.support.js +22 -33
- package/src/sap/fe/core/library.support.ts +23 -0
- package/src/sap/fe/core/library.ts +420 -0
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +5 -3
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +4 -4
- package/src/sap/fe/core/messagebundle.properties +45 -13
- package/src/sap/fe/core/messagebundle_ar.properties +29 -7
- package/src/sap/fe/core/messagebundle_bg.properties +29 -7
- package/src/sap/fe/core/messagebundle_ca.properties +29 -7
- package/src/sap/fe/core/messagebundle_cs.properties +29 -7
- package/src/sap/fe/core/messagebundle_cy.properties +29 -7
- package/src/sap/fe/core/messagebundle_da.properties +29 -7
- package/src/sap/fe/core/messagebundle_de.properties +29 -7
- package/src/sap/fe/core/messagebundle_el.properties +29 -7
- package/src/sap/fe/core/messagebundle_en.properties +29 -7
- package/src/sap/fe/core/messagebundle_en_GB.properties +29 -7
- package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +29 -7
- package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +29 -7
- package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +29 -7
- package/src/sap/fe/core/messagebundle_es.properties +29 -7
- package/src/sap/fe/core/messagebundle_es_MX.properties +29 -7
- package/src/sap/fe/core/messagebundle_et.properties +29 -7
- package/src/sap/fe/core/messagebundle_fi.properties +30 -8
- package/src/sap/fe/core/messagebundle_fr.properties +31 -9
- package/src/sap/fe/core/messagebundle_fr_CA.properties +31 -9
- package/src/sap/fe/core/messagebundle_hi.properties +29 -7
- package/src/sap/fe/core/messagebundle_hr.properties +29 -7
- package/src/sap/fe/core/messagebundle_hu.properties +29 -7
- package/src/sap/fe/core/messagebundle_id.properties +29 -7
- package/src/sap/fe/core/messagebundle_it.properties +29 -7
- package/src/sap/fe/core/messagebundle_iw.properties +29 -7
- package/src/sap/fe/core/messagebundle_ja.properties +28 -6
- package/src/sap/fe/core/messagebundle_kk.properties +29 -7
- package/src/sap/fe/core/messagebundle_ko.properties +29 -7
- package/src/sap/fe/core/messagebundle_lt.properties +29 -7
- package/src/sap/fe/core/messagebundle_lv.properties +30 -8
- package/src/sap/fe/core/messagebundle_ms.properties +29 -7
- package/src/sap/fe/core/messagebundle_nl.properties +29 -7
- package/src/sap/fe/core/messagebundle_no.properties +29 -7
- package/src/sap/fe/core/messagebundle_pl.properties +29 -7
- package/src/sap/fe/core/messagebundle_pt.properties +30 -8
- package/src/sap/fe/core/messagebundle_pt_PT.properties +29 -7
- package/src/sap/fe/core/messagebundle_ro.properties +29 -7
- package/src/sap/fe/core/messagebundle_ru.properties +29 -7
- package/src/sap/fe/core/messagebundle_sh.properties +29 -7
- package/src/sap/fe/core/messagebundle_sk.properties +29 -7
- package/src/sap/fe/core/messagebundle_sl.properties +29 -7
- package/src/sap/fe/core/messagebundle_sv.properties +30 -8
- package/src/sap/fe/core/messagebundle_th.properties +28 -6
- package/src/sap/fe/core/messagebundle_tr.properties +32 -10
- package/src/sap/fe/core/messagebundle_uk.properties +29 -7
- package/src/sap/fe/core/messagebundle_vi.properties +29 -7
- package/src/sap/fe/core/messagebundle_zh_CN.properties +29 -7
- package/src/sap/fe/core/messagebundle_zh_TW.properties +29 -7
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +47 -73
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +1 -1
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +158 -196
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +5 -6
- package/src/sap/fe/core/services/EnvironmentServiceFactory.js +70 -96
- package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +7 -6
- package/src/sap/fe/core/services/NavigationServiceFactory.js +287 -342
- package/src/sap/fe/core/services/NavigationServiceFactory.ts +11 -14
- package/src/sap/fe/core/services/ResourceModelServiceFactory.js +70 -105
- package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +6 -3
- package/src/sap/fe/core/services/RoutingServiceFactory.js +796 -820
- package/src/sap/fe/core/services/RoutingServiceFactory.ts +62 -53
- package/src/sap/fe/core/services/ShellServicesFactory.js +694 -741
- package/src/sap/fe/core/services/ShellServicesFactory.ts +33 -33
- package/src/sap/fe/core/services/SideEffectsServiceFactory.js +570 -595
- package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +23 -4
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +357 -389
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +25 -29
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +43 -5
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +7 -4
- package/src/sap/fe/core/support/CommonHelper.js +1 -1
- package/src/sap/fe/core/support/CommonHelper.ts +1 -4
- package/src/sap/fe/core/support/Diagnostics.js +36 -48
- package/src/sap/fe/core/templating/DataModelPathHelper.js +91 -90
- package/src/sap/fe/core/templating/DataModelPathHelper.ts +126 -123
- package/src/sap/fe/core/templating/DisplayModeFormatter.js +23 -3
- package/src/sap/fe/core/templating/DisplayModeFormatter.ts +26 -5
- package/src/sap/fe/core/templating/FilterHelper.js +25 -32
- package/src/sap/fe/core/templating/FilterHelper.ts +36 -35
- package/src/sap/fe/core/templating/PropertyHelper.js +16 -2
- package/src/sap/fe/core/templating/PropertyHelper.ts +31 -24
- package/src/sap/fe/core/templating/UIFormatters.js +150 -44
- package/src/sap/fe/core/templating/UIFormatters.ts +165 -67
- package/src/sap/fe/core/type/Email.js +26 -8
- package/src/sap/fe/core/type/Email.ts +8 -7
- package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +0 -75
|
@@ -0,0 +1,1001 @@
|
|
|
1
|
+
import Log from "sap/base/Log";
|
|
2
|
+
import ActivitySync from "sap/fe/core/actions/collaboration/ActivitySync";
|
|
3
|
+
import draft from "sap/fe/core/actions/draft";
|
|
4
|
+
import AppComponent from "sap/fe/core/AppComponent";
|
|
5
|
+
import BusyLocker from "sap/fe/core/BusyLocker";
|
|
6
|
+
import CommonUtils from "sap/fe/core/CommonUtils";
|
|
7
|
+
import {
|
|
8
|
+
defineUI5Class,
|
|
9
|
+
EnhanceWithUI5,
|
|
10
|
+
extensible,
|
|
11
|
+
finalExtension,
|
|
12
|
+
methodOverride,
|
|
13
|
+
publicExtension
|
|
14
|
+
} from "sap/fe/core/helpers/ClassSupport";
|
|
15
|
+
import EditState from "sap/fe/core/helpers/EditState";
|
|
16
|
+
import ModelHelper from "sap/fe/core/helpers/ModelHelper";
|
|
17
|
+
import SemanticKeyHelper from "sap/fe/core/helpers/SemanticKeyHelper";
|
|
18
|
+
import FELibrary from "sap/fe/core/library";
|
|
19
|
+
import PageController from "sap/fe/core/PageController";
|
|
20
|
+
import RouterProxy from "sap/fe/core/RouterProxy";
|
|
21
|
+
import { RoutingService } from "sap/fe/core/services/RoutingServiceFactory";
|
|
22
|
+
import TemplateComponent from "sap/fe/core/TemplateComponent";
|
|
23
|
+
import Event from "sap/ui/base/Event";
|
|
24
|
+
import Component from "sap/ui/core/Component";
|
|
25
|
+
import Core from "sap/ui/core/Core";
|
|
26
|
+
import ControllerExtension from "sap/ui/core/mvc/ControllerExtension";
|
|
27
|
+
import OverrideExecution from "sap/ui/core/mvc/OverrideExecution";
|
|
28
|
+
import View from "sap/ui/core/mvc/View";
|
|
29
|
+
import Router from "sap/ui/core/routing/Router";
|
|
30
|
+
import Filter from "sap/ui/model/Filter";
|
|
31
|
+
import FilterOperator from "sap/ui/model/FilterOperator";
|
|
32
|
+
import JSONModel from "sap/ui/model/json/JSONModel";
|
|
33
|
+
import Context from "sap/ui/model/odata/v4/Context";
|
|
34
|
+
import { CoreEx } from "types/extension_types";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* {@link sap.ui.core.mvc.ControllerExtension Controller extension}
|
|
38
|
+
*
|
|
39
|
+
* @namespace
|
|
40
|
+
* @alias sap.fe.core.controllerextensions.InternalRouting
|
|
41
|
+
*
|
|
42
|
+
* @private
|
|
43
|
+
* @since 1.74.0
|
|
44
|
+
*/
|
|
45
|
+
@defineUI5Class("sap.fe.core.controllerextensions.InternalRouting")
|
|
46
|
+
class InternalRouting extends ControllerExtension {
|
|
47
|
+
private base!: PageController;
|
|
48
|
+
private _oView!: View;
|
|
49
|
+
private _oAppComponent!: AppComponent;
|
|
50
|
+
private _oPageComponent!: EnhanceWithUI5<TemplateComponent> | null;
|
|
51
|
+
private _oRouter!: Router;
|
|
52
|
+
private _oRoutingService!: RoutingService;
|
|
53
|
+
private _oRouterProxy!: RouterProxy;
|
|
54
|
+
private _fnRouteMatchedBound!: Function;
|
|
55
|
+
private _oTargetInformation: any;
|
|
56
|
+
|
|
57
|
+
@methodOverride()
|
|
58
|
+
onExit() {
|
|
59
|
+
this._oRoutingService && this._oRoutingService.detachRouteMatched(this._fnRouteMatchedBound);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@methodOverride()
|
|
63
|
+
onInit() {
|
|
64
|
+
this._oView = this.base.getView();
|
|
65
|
+
this._oAppComponent = CommonUtils.getAppComponent(this._oView);
|
|
66
|
+
this._oPageComponent = Component.getOwnerComponentFor(this._oView) as EnhanceWithUI5<TemplateComponent>;
|
|
67
|
+
this._oRouter = this._oAppComponent.getRouter();
|
|
68
|
+
this._oRouterProxy = (this._oAppComponent as any).getRouterProxy();
|
|
69
|
+
|
|
70
|
+
if (!this._oAppComponent || !this._oPageComponent) {
|
|
71
|
+
throw new Error("Failed to initialize controler extension 'sap.fe.core.controllerextesions.InternalRouting");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
if (this._oAppComponent === this._oPageComponent) {
|
|
77
|
+
// The view isn't hosted in a dedicated UIComponent, but directly in the app
|
|
78
|
+
// --> just keep the view
|
|
79
|
+
this._oPageComponent = null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this._oAppComponent
|
|
83
|
+
.getService("routingService")
|
|
84
|
+
.then((oRoutingService: RoutingService) => {
|
|
85
|
+
this._oRoutingService = oRoutingService;
|
|
86
|
+
this._fnRouteMatchedBound = this._onRouteMatched.bind(this);
|
|
87
|
+
this._oRoutingService.attachRouteMatched(this._fnRouteMatchedBound);
|
|
88
|
+
this._oTargetInformation = oRoutingService.getTargetInformationFor(this._oPageComponent || this._oView);
|
|
89
|
+
})
|
|
90
|
+
.catch(function () {
|
|
91
|
+
throw new Error("This controller extension cannot work without a 'routingService' on the main AppComponent");
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Triggered every time this controller is a navigation target.
|
|
97
|
+
*/
|
|
98
|
+
@publicExtension()
|
|
99
|
+
@extensible(OverrideExecution.After)
|
|
100
|
+
onRouteMatched() {
|
|
101
|
+
/**/
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@publicExtension()
|
|
105
|
+
@extensible(OverrideExecution.After)
|
|
106
|
+
onRouteMatchedFinished() {
|
|
107
|
+
/**/
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@publicExtension()
|
|
111
|
+
@extensible(OverrideExecution.After)
|
|
112
|
+
onBeforeBinding(oBindingContext: any, mParameters?: any) {
|
|
113
|
+
const oRouting = (this.base.getView().getController() as any).routing;
|
|
114
|
+
if (oRouting && oRouting.onBeforeBinding) {
|
|
115
|
+
oRouting.onBeforeBinding(oBindingContext, mParameters);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@publicExtension()
|
|
120
|
+
@extensible(OverrideExecution.After)
|
|
121
|
+
onAfterBinding(oBindingContext: any, mParameters?: any) {
|
|
122
|
+
(this._oAppComponent as any).getRootViewController().onContextBoundToView(oBindingContext);
|
|
123
|
+
const oRouting = (this.base.getView().getController() as any).routing;
|
|
124
|
+
if (oRouting && oRouting.onAfterBinding) {
|
|
125
|
+
oRouting.onAfterBinding(oBindingContext, mParameters);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
///////////////////////////////////////////////////////////
|
|
130
|
+
// Methods triggering a navigation after a user action
|
|
131
|
+
// (e.g. click on a table row, button, etc...)
|
|
132
|
+
///////////////////////////////////////////////////////////
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Navigates to the specified navigation target.
|
|
136
|
+
*
|
|
137
|
+
* @param {sap.ui.model.odata.v4.Context} oContext Context instance
|
|
138
|
+
* @param {string} sNavigationTargetName Navigation target name
|
|
139
|
+
* @param {object} oSemanticObject Semantic object
|
|
140
|
+
* @param {boolean} bPreserveHistory True to force the new URL to be added at the end of the browser history (no replace)
|
|
141
|
+
* @ui5-restricted
|
|
142
|
+
*/
|
|
143
|
+
@publicExtension()
|
|
144
|
+
navigateToTarget(oContext: any, sNavigationTargetName: string, oSemanticObject?: object, bPreserveHistory?: boolean) {
|
|
145
|
+
const oNavigationConfiguration =
|
|
146
|
+
this._oPageComponent &&
|
|
147
|
+
this._oPageComponent.getNavigationConfiguration &&
|
|
148
|
+
this._oPageComponent.getNavigationConfiguration(sNavigationTargetName);
|
|
149
|
+
if (oNavigationConfiguration) {
|
|
150
|
+
const oDetailRoute = oNavigationConfiguration.detail;
|
|
151
|
+
const sRouteName = oDetailRoute.route;
|
|
152
|
+
const mParameterMapping = oDetailRoute.parameters;
|
|
153
|
+
this._oRoutingService.navigateTo(oContext, sRouteName, mParameterMapping, bPreserveHistory);
|
|
154
|
+
} else {
|
|
155
|
+
this._oRoutingService.navigateTo(oContext, null, null, bPreserveHistory);
|
|
156
|
+
}
|
|
157
|
+
this._oView.getViewData();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Navigates to the specified navigation target route.
|
|
162
|
+
*
|
|
163
|
+
* @param {string} sTargetRouteName Name of the target route
|
|
164
|
+
* @param {object} [oParameters] Parameters to be used with route to create the target hash
|
|
165
|
+
* @returns {Promise} Promise that is resolved when the navigation is finalized
|
|
166
|
+
* @ui5-restricted
|
|
167
|
+
*/
|
|
168
|
+
@publicExtension()
|
|
169
|
+
navigateToRoute(sTargetRouteName: string, oParameters?: object) {
|
|
170
|
+
return this._oRoutingService.navigateToRoute(sTargetRouteName, oParameters);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Navigates to a specific context.
|
|
175
|
+
*
|
|
176
|
+
* @param {sap.ui.model.odata.v4.Context} oContext The context to be navigated to
|
|
177
|
+
* @param {object} [mParameters] Optional navigation parameters
|
|
178
|
+
* @returns {Promise} Promise resolved when the navigation has been triggered
|
|
179
|
+
*
|
|
180
|
+
* @ui5-restricted
|
|
181
|
+
*/
|
|
182
|
+
@publicExtension()
|
|
183
|
+
@finalExtension()
|
|
184
|
+
navigateToContext(oContext: any, mParameters?: any): Promise<void> {
|
|
185
|
+
const oContextInfo: any = {};
|
|
186
|
+
mParameters = mParameters || {};
|
|
187
|
+
|
|
188
|
+
if (oContext.isA("sap.ui.model.odata.v4.ODataListBinding")) {
|
|
189
|
+
if (mParameters.asyncContext) {
|
|
190
|
+
// the context is either created async (Promise)
|
|
191
|
+
// We need to activate the routeMatchSynchro on the RouterProxy to avoid that
|
|
192
|
+
// the subsequent call to navigateToContext conflicts with the current one
|
|
193
|
+
this._oRouterProxy.activateRouteMatchSynchronization();
|
|
194
|
+
|
|
195
|
+
mParameters.asyncContext
|
|
196
|
+
.then((oContext: any) => {
|
|
197
|
+
// once the context is returned we navigate into it
|
|
198
|
+
this.navigateToContext(oContext, {
|
|
199
|
+
checkNoHashChange: mParameters.checkNoHashChange,
|
|
200
|
+
editable: mParameters.editable,
|
|
201
|
+
bPersistOPScroll: mParameters.bPersistOPScroll,
|
|
202
|
+
updateFCLLevel: mParameters.updateFCLLevel,
|
|
203
|
+
bForceFocus: mParameters.bForceFocus,
|
|
204
|
+
bNavigateToSiblingEntity: mParameters.bNavigateToSiblingEntity
|
|
205
|
+
});
|
|
206
|
+
})
|
|
207
|
+
.catch(function (oError: any) {
|
|
208
|
+
Log.error("Error with the async context", oError);
|
|
209
|
+
});
|
|
210
|
+
} else if (!mParameters.bDeferredContext) {
|
|
211
|
+
// Navigate to a list binding not yet supported
|
|
212
|
+
throw "navigation to a list binding is not yet supported";
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (mParameters.callExtension) {
|
|
217
|
+
const oInternalModel = this._oView.getModel("internal") as JSONModel;
|
|
218
|
+
oInternalModel.setProperty("/paginatorCurrentContext", null);
|
|
219
|
+
|
|
220
|
+
oContextInfo.sourceBindingContext = oContext.getObject();
|
|
221
|
+
oContextInfo.bindingContext = oContext;
|
|
222
|
+
if (mParameters.oEvent) {
|
|
223
|
+
oContextInfo.oEvent = mParameters.oEvent;
|
|
224
|
+
}
|
|
225
|
+
// Storing the selected context to use it in internal route navigation if neccessary.
|
|
226
|
+
const bOverrideNav = (this.base.getView().getController() as any).routing.onBeforeNavigation(oContextInfo);
|
|
227
|
+
if (bOverrideNav) {
|
|
228
|
+
oInternalModel.setProperty("/paginatorCurrentContext", oContext);
|
|
229
|
+
return Promise.resolve();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
mParameters.FCLLevel = this._getFCLLevel();
|
|
233
|
+
|
|
234
|
+
return this._oRoutingService.navigateToContext(oContext, mParameters, this._oView.getViewData(), this._oTargetInformation);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Navigates backwards from a context.
|
|
239
|
+
*
|
|
240
|
+
* @param {sap.ui.model.odata.v4.Context} oContext Context to be navigated from
|
|
241
|
+
* @param {object} [mParameters] Optional navigation parameters
|
|
242
|
+
* @returns {Promise} Promise resolved when the navigation has been triggered
|
|
243
|
+
*
|
|
244
|
+
* @ui5-restricted
|
|
245
|
+
*/
|
|
246
|
+
@publicExtension()
|
|
247
|
+
@finalExtension()
|
|
248
|
+
navigateBackFromContext(oContext: any, mParameters?: any) {
|
|
249
|
+
mParameters = mParameters || {};
|
|
250
|
+
mParameters.updateFCLLevel = -1;
|
|
251
|
+
|
|
252
|
+
return this.navigateToContext(oContext, mParameters);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Navigates forwards to a context.
|
|
257
|
+
*
|
|
258
|
+
* @param {sap.ui.model.odata.v4.Context} oContext Context to be navigated to
|
|
259
|
+
* @param {object} mParameters Optional navigation parameters
|
|
260
|
+
* @returns {Promise} Promise resolved when the navigation has been triggered
|
|
261
|
+
*
|
|
262
|
+
* @ui5-restricted
|
|
263
|
+
*/
|
|
264
|
+
@publicExtension()
|
|
265
|
+
@finalExtension()
|
|
266
|
+
navigateForwardToContext(oContext: any, mParameters?: any) {
|
|
267
|
+
if (this._oView.getBindingContext("internal")?.getProperty("messageFooterContainsErrors") === true) {
|
|
268
|
+
return Promise.resolve();
|
|
269
|
+
}
|
|
270
|
+
mParameters = mParameters || {};
|
|
271
|
+
mParameters.updateFCLLevel = 1;
|
|
272
|
+
|
|
273
|
+
return this.navigateToContext(oContext, mParameters);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Navigates back in history if the current hash corresponds to a transient state.
|
|
278
|
+
*/
|
|
279
|
+
@publicExtension()
|
|
280
|
+
@finalExtension()
|
|
281
|
+
navigateBackFromTransientState() {
|
|
282
|
+
const sHash = this._oRouterProxy.getHash();
|
|
283
|
+
|
|
284
|
+
// if triggered while navigating to (...), we need to navigate back
|
|
285
|
+
if (sHash.indexOf("(...)") !== -1) {
|
|
286
|
+
this._oRouterProxy.navBack();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
@publicExtension()
|
|
291
|
+
@finalExtension()
|
|
292
|
+
navigateToMessagePage(sErrorMessage: any, mParameters: any) {
|
|
293
|
+
mParameters = mParameters || {};
|
|
294
|
+
if (this._oRouterProxy.getHash().indexOf("i-action=create") > -1) {
|
|
295
|
+
return this._oRouterProxy.navToHash(this._oRoutingService.getDefaultCreateHash());
|
|
296
|
+
} else {
|
|
297
|
+
mParameters.FCLLevel = this._getFCLLevel();
|
|
298
|
+
|
|
299
|
+
return (this._oAppComponent as any).getRootViewController().displayMessagePage(sErrorMessage, mParameters);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Checks if one of the current views on the screen is bound to a given context.
|
|
305
|
+
*
|
|
306
|
+
* @param {sap.ui.model.odata.v4.Context} oContext
|
|
307
|
+
* @returns {boolean}
|
|
308
|
+
*
|
|
309
|
+
* @ui5-restricted
|
|
310
|
+
*/
|
|
311
|
+
@publicExtension()
|
|
312
|
+
@finalExtension()
|
|
313
|
+
isCurrentStateImpactedBy(oContext: any) {
|
|
314
|
+
return this._oRoutingService.isCurrentStateImpactedBy(oContext);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
///////////////////////////////////////////////////////////
|
|
318
|
+
// Methods to bind the page when a route is matched
|
|
319
|
+
///////////////////////////////////////////////////////////
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Called when a route is matched.
|
|
323
|
+
* Builds the binding context from the navigation parameters, and bind the page accordingly.
|
|
324
|
+
*
|
|
325
|
+
* @param {object} oEvent
|
|
326
|
+
*
|
|
327
|
+
* @ui5-restricted
|
|
328
|
+
*/
|
|
329
|
+
_onRouteMatched(oEvent: Event) {
|
|
330
|
+
// Check if the target for this view is part of the event targets
|
|
331
|
+
const aTargets = oEvent.getParameter("routeInformation") && oEvent.getParameter("routeInformation").targets;
|
|
332
|
+
if (!aTargets || aTargets.indexOf(this._oTargetInformation.targetName) === -1) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Retrieve the binding context pattern
|
|
337
|
+
let sTarget;
|
|
338
|
+
if (this._oPageComponent && this._oPageComponent.getBindingContextPattern) {
|
|
339
|
+
sTarget = this._oPageComponent.getBindingContextPattern();
|
|
340
|
+
}
|
|
341
|
+
sTarget = sTarget || this._oTargetInformation.contextPattern;
|
|
342
|
+
|
|
343
|
+
if (sTarget === null || sTarget === undefined) {
|
|
344
|
+
// Don't do this if we already got sTarget == '', which is a valid target pattern
|
|
345
|
+
sTarget = oEvent.getParameter("routePattern");
|
|
346
|
+
}
|
|
347
|
+
sTarget = sTarget.replace(":?query:", "");
|
|
348
|
+
|
|
349
|
+
// Replace the parameters by their values in the binding context pattern
|
|
350
|
+
const mArguments = (oEvent.getParameters() as any).arguments;
|
|
351
|
+
let bDeferred = false;
|
|
352
|
+
const oNavigationParameters = oEvent.getParameter("navigationInfo");
|
|
353
|
+
|
|
354
|
+
for (const sKey in mArguments) {
|
|
355
|
+
const sValue = mArguments[sKey];
|
|
356
|
+
if (sValue === "..." && sTarget.indexOf("{" + sKey + "}") >= 0) {
|
|
357
|
+
bDeferred = true;
|
|
358
|
+
// Sometimes in preferredMode = create, the edit button is shown in background when the
|
|
359
|
+
// action parameter dialog shows up, setting bTargetEditable passes editable as true
|
|
360
|
+
// to onBeforeBinding in _bindTargetPage function
|
|
361
|
+
oNavigationParameters.bTargetEditable = true;
|
|
362
|
+
}
|
|
363
|
+
sTarget = sTarget.replace("{" + sKey + "}", sValue);
|
|
364
|
+
}
|
|
365
|
+
if (mArguments["?query"] && mArguments["?query"].hasOwnProperty("i-action")) {
|
|
366
|
+
oNavigationParameters.bActionCreate = true;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// the binding target is always absolute
|
|
370
|
+
if (sTarget && sTarget[0] !== "/") {
|
|
371
|
+
sTarget = "/" + sTarget;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
this.onRouteMatched();
|
|
375
|
+
|
|
376
|
+
const oModel = this._oView.getModel();
|
|
377
|
+
let oOut;
|
|
378
|
+
if (bDeferred) {
|
|
379
|
+
oOut = this._bindDeferred(sTarget, oNavigationParameters);
|
|
380
|
+
} else {
|
|
381
|
+
oOut = this._bindPage(sTarget, oModel, oNavigationParameters);
|
|
382
|
+
}
|
|
383
|
+
// eslint-disable-next-line promise/catch-or-return
|
|
384
|
+
oOut.finally(() => {
|
|
385
|
+
this.onRouteMatchedFinished();
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
(this._oAppComponent as any).getRootViewController().updateUIStateForView(this._oView, this._getFCLLevel());
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Deferred binding (during object creation).
|
|
393
|
+
*
|
|
394
|
+
* @param {string} sTargetPath The path to the deffered context
|
|
395
|
+
* @param {object} oNavigationParameters Navigation parameters
|
|
396
|
+
* @returns {Promise}
|
|
397
|
+
* @ui5-restricted
|
|
398
|
+
*/
|
|
399
|
+
_bindDeferred(sTargetPath: string, oNavigationParameters: any) {
|
|
400
|
+
this.onBeforeBinding(null, { editable: oNavigationParameters.bTargetEditable });
|
|
401
|
+
|
|
402
|
+
if (oNavigationParameters.bDeferredContext || !oNavigationParameters.oAsyncContext) {
|
|
403
|
+
// either the context shall be created in the target page (deferred Context) or it shall
|
|
404
|
+
// be created async but the user refreshed the page / bookmarked this URL
|
|
405
|
+
// TODO: currently the target component creates this document but we shall move this to
|
|
406
|
+
// a central place
|
|
407
|
+
if (this._oPageComponent && this._oPageComponent.createDeferredContext) {
|
|
408
|
+
this._oPageComponent.createDeferredContext(
|
|
409
|
+
sTargetPath,
|
|
410
|
+
oNavigationParameters.useContext,
|
|
411
|
+
oNavigationParameters.bActionCreate
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (this._getBindingContext() && this._getBindingContext().hasPendingChanges()) {
|
|
417
|
+
// For now remove the pending changes to avoid the model raises errors and the object page is at least bound
|
|
418
|
+
// Ideally the user should be asked for
|
|
419
|
+
this._getBindingContext().getBinding().resetChanges();
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// remove the context to avoid showing old data
|
|
423
|
+
this._setBindingContext(null);
|
|
424
|
+
|
|
425
|
+
this.onAfterBinding(null);
|
|
426
|
+
return Promise.resolve();
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Sets the binding context of the page from a path.
|
|
431
|
+
*
|
|
432
|
+
* @param {string} sTargetPath The path to the context
|
|
433
|
+
* @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
|
|
434
|
+
* @param {object} oNavigationParameters Navigation parameters
|
|
435
|
+
* @returns {Promise}
|
|
436
|
+
* @ui5-restricted
|
|
437
|
+
*/
|
|
438
|
+
_bindPage(sTargetPath: string, oModel: any, oNavigationParameters: object) {
|
|
439
|
+
if (sTargetPath === "") {
|
|
440
|
+
return Promise.resolve(this._bindPageToContext(null, oModel, oNavigationParameters));
|
|
441
|
+
} else {
|
|
442
|
+
return this._resolveSemanticPath(sTargetPath, oModel)
|
|
443
|
+
.then((sTechnicalPath: any) => {
|
|
444
|
+
this._bindPageToPath(sTechnicalPath, oModel, oNavigationParameters);
|
|
445
|
+
})
|
|
446
|
+
.catch((oError: any) => {
|
|
447
|
+
// Error handling for erroneous metadata request
|
|
448
|
+
const oResourceBundle = (Core as CoreEx).getLibraryResourceBundle("sap.fe.core");
|
|
449
|
+
|
|
450
|
+
this.navigateToMessagePage(oResourceBundle.getText("C_COMMON_SAPFE_DATA_RECEIVED_ERROR"), {
|
|
451
|
+
title: oResourceBundle.getText("C_COMMON_SAPFE_ERROR"),
|
|
452
|
+
description: oError.message
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Creates the filter to retrieve a context corresponding to a semantic path.
|
|
460
|
+
*
|
|
461
|
+
* @param {string} sSemanticPath The semantic path
|
|
462
|
+
* @param {Array} aSemanticKeys The semantic keys for the path
|
|
463
|
+
* @param {object} oMetaModel The instance of the meta model
|
|
464
|
+
* @returns {sap.ui.model.Filter} The filter
|
|
465
|
+
*
|
|
466
|
+
* @ui5-restricted
|
|
467
|
+
*/
|
|
468
|
+
_createFilterFromSemanticPath(sSemanticPath: string, aSemanticKeys: any[], oMetaModel: object) {
|
|
469
|
+
const fnUnquoteAndDecode = function (sValue: any) {
|
|
470
|
+
if (sValue.indexOf("'") === 0 && sValue.lastIndexOf("'") === sValue.length - 1) {
|
|
471
|
+
// Remove the quotes from the value and decode special chars
|
|
472
|
+
sValue = decodeURIComponent(sValue.substring(1, sValue.length - 1));
|
|
473
|
+
}
|
|
474
|
+
return sValue;
|
|
475
|
+
};
|
|
476
|
+
const aKeyValues = sSemanticPath.substring(sSemanticPath.indexOf("(") + 1, sSemanticPath.length - 1).split(",");
|
|
477
|
+
let aFilters: Filter[];
|
|
478
|
+
|
|
479
|
+
if (aSemanticKeys.length != aKeyValues.length) {
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const bFilteringCaseSensitive = ModelHelper.isFilteringCaseSensitive(oMetaModel);
|
|
484
|
+
|
|
485
|
+
if (aSemanticKeys.length === 1) {
|
|
486
|
+
// Take the first key value
|
|
487
|
+
const sKeyValue = fnUnquoteAndDecode(aKeyValues[0]);
|
|
488
|
+
aFilters = [
|
|
489
|
+
new Filter({
|
|
490
|
+
path: aSemanticKeys[0].$PropertyPath,
|
|
491
|
+
operator: FilterOperator.EQ,
|
|
492
|
+
value1: sKeyValue,
|
|
493
|
+
caseSensitive: bFilteringCaseSensitive
|
|
494
|
+
})
|
|
495
|
+
];
|
|
496
|
+
} else {
|
|
497
|
+
const mKeyValues: any = {};
|
|
498
|
+
// Create a map of all key values
|
|
499
|
+
aKeyValues.forEach(function (sKeyAssignment: string) {
|
|
500
|
+
const aParts = sKeyAssignment.split("="),
|
|
501
|
+
sKeyValue = fnUnquoteAndDecode(aParts[1]);
|
|
502
|
+
|
|
503
|
+
mKeyValues[aParts[0]] = sKeyValue;
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
let bFailed = false;
|
|
507
|
+
aFilters = aSemanticKeys.map(function (oSemanticKey: any) {
|
|
508
|
+
const sKey = oSemanticKey.$PropertyPath,
|
|
509
|
+
sValue = mKeyValues[sKey];
|
|
510
|
+
|
|
511
|
+
if (sValue !== undefined) {
|
|
512
|
+
return new Filter({
|
|
513
|
+
path: sKey,
|
|
514
|
+
operator: FilterOperator.EQ,
|
|
515
|
+
value1: sValue,
|
|
516
|
+
caseSensitive: bFilteringCaseSensitive
|
|
517
|
+
});
|
|
518
|
+
} else {
|
|
519
|
+
bFailed = true;
|
|
520
|
+
return new Filter({
|
|
521
|
+
path: "XX"
|
|
522
|
+
}); // will be ignore anyway since we return after
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
if (bFailed) {
|
|
527
|
+
return null;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// Add a draft filter to make sure we take the draft entity if there is one
|
|
532
|
+
// Or the active entity otherwise
|
|
533
|
+
const oDraftFilter = new Filter({
|
|
534
|
+
filters: [new Filter("IsActiveEntity", "EQ", false), new Filter("SiblingEntity/IsActiveEntity", "EQ", null)],
|
|
535
|
+
and: false
|
|
536
|
+
});
|
|
537
|
+
aFilters.push(oDraftFilter);
|
|
538
|
+
|
|
539
|
+
const oCombinedFilter = new Filter(aFilters, true);
|
|
540
|
+
return oCombinedFilter;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Converts a path with semantic keys to a path with technical keys.
|
|
545
|
+
*
|
|
546
|
+
* @param {string} sSemanticPath The path with semantic keys
|
|
547
|
+
* @param {sap.ui.model.odata.v4.ODataModel} oModel The model for the path
|
|
548
|
+
* @param {Array} aSemanticKeys The semantic keys for the path
|
|
549
|
+
* @returns {Promise} A Promise containing the path with technical keys if sSemanticPath could be interpreted as a semantic path, null otherwise
|
|
550
|
+
*
|
|
551
|
+
* @ui5-restricted
|
|
552
|
+
*/
|
|
553
|
+
_getTechnicalPathFromSemanticPath(sSemanticPath: string, oModel: any, aSemanticKeys: any[]) {
|
|
554
|
+
const oMetaModel = oModel.getMetaModel();
|
|
555
|
+
let sEntitySetPath = oMetaModel.getMetaContext(sSemanticPath).getPath();
|
|
556
|
+
|
|
557
|
+
if (!aSemanticKeys || aSemanticKeys.length === 0) {
|
|
558
|
+
// No semantic keys
|
|
559
|
+
return Promise.resolve(null);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Create a set of filters corresponding to all keys
|
|
563
|
+
const oFilter = this._createFilterFromSemanticPath(sSemanticPath, aSemanticKeys, oMetaModel);
|
|
564
|
+
if (oFilter === null) {
|
|
565
|
+
// Couldn't interpret the path as a semantic one
|
|
566
|
+
return Promise.resolve(null);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Load the corresponding object
|
|
570
|
+
if (!sEntitySetPath?.startsWith("/")) {
|
|
571
|
+
sEntitySetPath = "/" + sEntitySetPath;
|
|
572
|
+
}
|
|
573
|
+
const oListBinding = oModel.bindList(sEntitySetPath, undefined, undefined, oFilter, {
|
|
574
|
+
"$$groupId": "$auto.Heroes"
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
return oListBinding.requestContexts(0, 2).then(function (oContexts: any) {
|
|
578
|
+
if (oContexts && oContexts.length) {
|
|
579
|
+
return oContexts[0].getPath();
|
|
580
|
+
} else {
|
|
581
|
+
// No data could be loaded
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Checks if a path is eligible for semantic bookmarking.
|
|
589
|
+
*
|
|
590
|
+
* @param {string} sPath The path to test
|
|
591
|
+
* @param {sap.ui.model.odata.v4.ODataMetaModel} oMetaModel The associated metadata model
|
|
592
|
+
* @returns {boolean} `true` if the path is eligible
|
|
593
|
+
*
|
|
594
|
+
* @ui5-restricted
|
|
595
|
+
*/
|
|
596
|
+
_checkPathForSemanticBookmarking(sPath: string, oMetaModel: any) {
|
|
597
|
+
// Only path on root objects allow semantic bookmarking, i.e. sPath = xxx(yyy)
|
|
598
|
+
const aMatches = /^[\/]?(\w+)\([^\/]+\)$/.exec(sPath);
|
|
599
|
+
if (!aMatches) {
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
// Get the entitySet name
|
|
603
|
+
const sEntitySetPath = "/" + aMatches[1];
|
|
604
|
+
// Check the entity set supports draft (otherwise we don't support semantic bookmarking)
|
|
605
|
+
const oDraftRoot = oMetaModel.getObject(sEntitySetPath + "@com.sap.vocabularies.Common.v1.DraftRoot");
|
|
606
|
+
const oDraftNode = oMetaModel.getObject(sEntitySetPath + "@com.sap.vocabularies.Common.v1.DraftNode");
|
|
607
|
+
return oDraftRoot || oDraftNode ? true : false;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Builds a path with semantic keys from a path with technical keys.
|
|
612
|
+
* @param {string} sPathToResolve The path to be transformed
|
|
613
|
+
* @param oModel
|
|
614
|
+
* @returns {Promise} String promise for the new path. If sPathToResolved couldn't be interpreted as a semantic path, it is returned as is.
|
|
615
|
+
* @ui5-restricted
|
|
616
|
+
*/
|
|
617
|
+
_resolveSemanticPath(sPathToResolve: string, oModel: any): Promise<string> {
|
|
618
|
+
const oMetaModel = oModel.getMetaModel();
|
|
619
|
+
const oLastSemanticMapping = this._oRoutingService.getLastSemanticMapping();
|
|
620
|
+
let sCurrentHashNoParams = this._oRouter.getHashChanger().getHash().split("?")[0];
|
|
621
|
+
|
|
622
|
+
if (sCurrentHashNoParams && sCurrentHashNoParams.lastIndexOf("/") === sCurrentHashNoParams.length - 1) {
|
|
623
|
+
// Remove trailing '/'
|
|
624
|
+
sCurrentHashNoParams = sCurrentHashNoParams.substring(0, sCurrentHashNoParams.length - 1);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
let sRootEntityName = sCurrentHashNoParams && sCurrentHashNoParams.substr(0, sCurrentHashNoParams.indexOf("("));
|
|
628
|
+
if (sRootEntityName.indexOf("/") === 0) {
|
|
629
|
+
sRootEntityName = sRootEntityName.substring(1);
|
|
630
|
+
}
|
|
631
|
+
const bAllowSemanticBookmark = this._checkPathForSemanticBookmarking(sCurrentHashNoParams, oMetaModel),
|
|
632
|
+
aSemanticKeys = bAllowSemanticBookmark && SemanticKeyHelper.getSemanticKeys(oMetaModel, sRootEntityName);
|
|
633
|
+
if (!aSemanticKeys) {
|
|
634
|
+
// No semantic keys available --> use the path as is
|
|
635
|
+
return Promise.resolve(sPathToResolve);
|
|
636
|
+
} else if (oLastSemanticMapping && oLastSemanticMapping.semanticPath === sPathToResolve) {
|
|
637
|
+
// This semantic path has been resolved previously
|
|
638
|
+
return Promise.resolve(oLastSemanticMapping.technicalPath);
|
|
639
|
+
} else {
|
|
640
|
+
// We need resolve the semantic path to get the technical keys
|
|
641
|
+
return this._getTechnicalPathFromSemanticPath(sCurrentHashNoParams, oModel, aSemanticKeys).then((sTechnicalPath: any) => {
|
|
642
|
+
if (sTechnicalPath && sTechnicalPath !== sPathToResolve) {
|
|
643
|
+
// The semantic path was resolved (otherwise keep the original value for target)
|
|
644
|
+
this._oRoutingService.setLastSemanticMapping({
|
|
645
|
+
technicalPath: sTechnicalPath,
|
|
646
|
+
semanticPath: sPathToResolve
|
|
647
|
+
});
|
|
648
|
+
return sTechnicalPath;
|
|
649
|
+
} else {
|
|
650
|
+
return sPathToResolve;
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Sets the binding context of the page from a path.
|
|
658
|
+
*
|
|
659
|
+
* @param {string} sTargetPath The path to build the context. Needs to contain technical keys only.
|
|
660
|
+
* @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
|
|
661
|
+
* @param {object} oNavigationParameters Navigation parameters
|
|
662
|
+
*
|
|
663
|
+
* @ui5-restricted
|
|
664
|
+
*/
|
|
665
|
+
_bindPageToPath(sTargetPath: string, oModel: any, oNavigationParameters: any) {
|
|
666
|
+
const oCurrentContext = this._getBindingContext(),
|
|
667
|
+
sCurrentPath = oCurrentContext && oCurrentContext.getPath(),
|
|
668
|
+
oUseContext = oNavigationParameters.useContext;
|
|
669
|
+
|
|
670
|
+
// We set the binding context only if it's different from the current one
|
|
671
|
+
// or if we have a context already selected
|
|
672
|
+
if (sCurrentPath !== sTargetPath || (oUseContext && oUseContext.getPath() === sTargetPath)) {
|
|
673
|
+
let oTargetContext;
|
|
674
|
+
if (oUseContext && oUseContext.getPath() === sTargetPath) {
|
|
675
|
+
// We already have the context to be used
|
|
676
|
+
oTargetContext = oUseContext;
|
|
677
|
+
} else {
|
|
678
|
+
// Otherwise we need to create it from sTargetPath
|
|
679
|
+
oTargetContext = this._createBindingContext(sTargetPath, oModel, oNavigationParameters.bNavigateToSiblingEntity);
|
|
680
|
+
}
|
|
681
|
+
if (oTargetContext !== oCurrentContext) {
|
|
682
|
+
this._bindPageToContext(oTargetContext, oModel, oNavigationParameters);
|
|
683
|
+
}
|
|
684
|
+
} else if (!oNavigationParameters.bReasonIsIappState && EditState.isEditStateDirty()) {
|
|
685
|
+
this._refreshBindingContext(oCurrentContext);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Binds the page to a context.
|
|
691
|
+
*
|
|
692
|
+
* @param {sap.ui.model.odata.v4.Context} oContext Context to be bound
|
|
693
|
+
* @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
|
|
694
|
+
* @param {object} oNavigationParameters Navigation parameters
|
|
695
|
+
*
|
|
696
|
+
* @ui5-restricted
|
|
697
|
+
*/
|
|
698
|
+
_bindPageToContext(oContext: any, oModel: any, oNavigationParameters: any) {
|
|
699
|
+
if (!oContext) {
|
|
700
|
+
this.onBeforeBinding(null);
|
|
701
|
+
this.onAfterBinding(null);
|
|
702
|
+
} else {
|
|
703
|
+
const oParentListBinding = oContext.getBinding();
|
|
704
|
+
|
|
705
|
+
if (!oContext.getBinding() || oContext.getBinding().isA("sap.ui.model.odata.v4.ODataListBinding")) {
|
|
706
|
+
// We need to recreate the context otherwise we get errors
|
|
707
|
+
oContext = this._createBindingContext(oContext.getPath(), oModel, oNavigationParameters.bNavigateToSiblingEntity);
|
|
708
|
+
if (EditState.isEditStateDirty()) {
|
|
709
|
+
// TODO: as a workaround we invalidate the model cache while the app is dirty
|
|
710
|
+
// as the manage model sets the parent in an async task and the request side effects
|
|
711
|
+
// relies on the parent relationship we have to set a timeout 0
|
|
712
|
+
setTimeout(() => {
|
|
713
|
+
this._refreshBindingContext(oContext);
|
|
714
|
+
}, 0);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// Set the binding context with the proper before/after callbacks
|
|
719
|
+
this.onBeforeBinding(oContext, {
|
|
720
|
+
editable: oNavigationParameters.bTargetEditable,
|
|
721
|
+
listBinding: oParentListBinding,
|
|
722
|
+
bPersistOPScroll: oNavigationParameters.bPersistOPScroll,
|
|
723
|
+
bDraftNavigation: oNavigationParameters.bDraftNavigation,
|
|
724
|
+
showPlaceholder: oNavigationParameters.bShowPlaceholder
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
this._setBindingContext(oContext);
|
|
728
|
+
this.onAfterBinding(oContext);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Creates a binding context from a path.
|
|
734
|
+
*
|
|
735
|
+
* @param {string} sPath The path
|
|
736
|
+
* @param {sap.ui.model.odata.v4.ODataModel} oModel The OData model
|
|
737
|
+
* @returns {sap.ui.model.odata.v4.Context} Created context
|
|
738
|
+
*
|
|
739
|
+
* @ui5-restricted
|
|
740
|
+
*/
|
|
741
|
+
@publicExtension()
|
|
742
|
+
_createBindingContext(sPath: string, oModel: any, navigateToSiblingEntity: boolean = true) {
|
|
743
|
+
const oPageComponent = this._oPageComponent,
|
|
744
|
+
sEntitySet = oPageComponent && oPageComponent.getEntitySet && oPageComponent.getEntitySet(),
|
|
745
|
+
sContextPath =
|
|
746
|
+
(oPageComponent && oPageComponent.getContextPath && oPageComponent.getContextPath()) || (sEntitySet && "/" + sEntitySet),
|
|
747
|
+
oMetaModel = oModel.getMetaModel(),
|
|
748
|
+
mParameters: any = {
|
|
749
|
+
$$patchWithoutSideEffects: true,
|
|
750
|
+
$$groupId: "$auto.Heroes",
|
|
751
|
+
$$updateGroupId: "$auto"
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
if (sEntitySet) {
|
|
755
|
+
const sMessagesPath = oMetaModel.getObject(sContextPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path");
|
|
756
|
+
if (sMessagesPath) {
|
|
757
|
+
mParameters.$select = sMessagesPath;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
// In case of draft: $select the state flags (HasActiveEntity, HasDraftEntity, and IsActiveEntity)
|
|
762
|
+
const oDraftRoot = oMetaModel.getObject(sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot");
|
|
763
|
+
const oDraftNode = oMetaModel.getObject(sContextPath + "@com.sap.vocabularies.Common.v1.DraftNode");
|
|
764
|
+
if (oDraftRoot || oDraftNode) {
|
|
765
|
+
if (mParameters.$select === undefined) {
|
|
766
|
+
mParameters.$select = "HasActiveEntity,HasDraftEntity,IsActiveEntity";
|
|
767
|
+
} else {
|
|
768
|
+
mParameters.$select += ",HasActiveEntity,HasDraftEntity,IsActiveEntity";
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
const oHiddenBinding = oModel.bindContext(sPath, undefined, mParameters);
|
|
773
|
+
|
|
774
|
+
oHiddenBinding.attachEventOnce("dataRequested", () => {
|
|
775
|
+
BusyLocker.lock(this._oView);
|
|
776
|
+
});
|
|
777
|
+
oHiddenBinding.attachEventOnce("dataReceived", this._dataReceivedEventHandler.bind(this, navigateToSiblingEntity));
|
|
778
|
+
return oHiddenBinding.getBoundContext();
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
async _dataReceivedEventHandler(navigateToSiblingEntity: boolean, oEvent: Event) {
|
|
782
|
+
const context = oEvent?.getSource && (oEvent?.getSource() as any)?.getBoundContext();
|
|
783
|
+
const ProgrammingModel = FELibrary.ProgrammingModel;
|
|
784
|
+
const programmingModel = (this._oView?.getController() as PageController)?._editFlow?.getProgrammingModel(context);
|
|
785
|
+
const sErrorDescription = oEvent && oEvent.getParameter("error");
|
|
786
|
+
BusyLocker.unlock(this._oView);
|
|
787
|
+
if (
|
|
788
|
+
programmingModel === ProgrammingModel.Draft &&
|
|
789
|
+
ActivitySync.isCollaborationEnabled(this._oView) &&
|
|
790
|
+
navigateToSiblingEntity &&
|
|
791
|
+
context.getProperty("IsActiveEntity") &&
|
|
792
|
+
context.getObject().DraftAdministrativeData
|
|
793
|
+
) {
|
|
794
|
+
const siblingInfo = await draft.computeSiblingInformation(context, context);
|
|
795
|
+
if (siblingInfo) {
|
|
796
|
+
this.navigateToContext(siblingInfo.targetContext);
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (sErrorDescription) {
|
|
802
|
+
// TODO: in case of 404 the text shall be different
|
|
803
|
+
try {
|
|
804
|
+
const oResourceBundle = await (Core as CoreEx).getLibraryResourceBundle("sap.fe.core", true);
|
|
805
|
+
const messageHandler = this.base.messageHandler;
|
|
806
|
+
let mParams = {};
|
|
807
|
+
if (sErrorDescription && sErrorDescription.status === 503) {
|
|
808
|
+
mParams = {
|
|
809
|
+
isInitialLoad503Error: true,
|
|
810
|
+
shellBack: true
|
|
811
|
+
};
|
|
812
|
+
} else {
|
|
813
|
+
mParams = {
|
|
814
|
+
title: oResourceBundle.getText("SAPFE_ERROR"),
|
|
815
|
+
description: sErrorDescription,
|
|
816
|
+
isDataReceivedError: true,
|
|
817
|
+
shellBack: true
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
messageHandler.showMessages(mParams);
|
|
821
|
+
} catch (oError: any) {
|
|
822
|
+
Log.error("Error while getting the core resource bundle", oError);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
/**
|
|
828
|
+
* Requests side effects on a binding context to "refresh" it.
|
|
829
|
+
* TODO: get rid of this once provided by the model
|
|
830
|
+
* a refresh on the binding context does not work in case a creation row with a transient context is
|
|
831
|
+
* used. also a requestSideEffects with an empty path would fail due to the transient context
|
|
832
|
+
* therefore we get all dependent bindings (via private model method) to determine all paths and then
|
|
833
|
+
* request them.
|
|
834
|
+
*
|
|
835
|
+
* @param {sap.ui.model.odata.v4.Context} oBindingContext Context to be refreshed
|
|
836
|
+
*
|
|
837
|
+
* @ui5-restricted
|
|
838
|
+
*/
|
|
839
|
+
_refreshBindingContext(oBindingContext: any) {
|
|
840
|
+
const oPageComponent = this._oPageComponent;
|
|
841
|
+
const oSideEffectsService = this._oAppComponent.getSideEffectsService();
|
|
842
|
+
const sRootContextPath = oBindingContext.getPath();
|
|
843
|
+
const sEntitySet = oPageComponent && oPageComponent.getEntitySet && oPageComponent.getEntitySet();
|
|
844
|
+
const sContextPath =
|
|
845
|
+
(oPageComponent && oPageComponent.getContextPath && oPageComponent.getContextPath()) || (sEntitySet && "/" + sEntitySet);
|
|
846
|
+
const oMetaModel = this._oView.getModel().getMetaModel();
|
|
847
|
+
let sMessagesPath;
|
|
848
|
+
const aNavigationPropertyPaths: any[] = [];
|
|
849
|
+
const aPropertyPaths: any[] = [];
|
|
850
|
+
const oSideEffects: any = {
|
|
851
|
+
TargetProperties: [],
|
|
852
|
+
TargetEntities: []
|
|
853
|
+
};
|
|
854
|
+
|
|
855
|
+
function getBindingPaths(oBinding: any) {
|
|
856
|
+
let aDependentBindings;
|
|
857
|
+
const sRelativePath = ((oBinding.getContext() && oBinding.getContext().getPath()) || "").replace(sRootContextPath, ""); // If no context, this is an absolute binding so no relative path
|
|
858
|
+
const sPath = (sRelativePath ? sRelativePath.slice(1) + "/" : sRelativePath) + oBinding.getPath();
|
|
859
|
+
|
|
860
|
+
if (oBinding.isA("sap.ui.model.odata.v4.ODataContextBinding")) {
|
|
861
|
+
// if (sPath === "") {
|
|
862
|
+
// now get the dependent bindings
|
|
863
|
+
aDependentBindings = oBinding.getDependentBindings();
|
|
864
|
+
if (aDependentBindings) {
|
|
865
|
+
// ask the dependent bindings (and only those with the specified groupId
|
|
866
|
+
//if (aDependentBindings.length > 0) {
|
|
867
|
+
for (let i = 0; i < aDependentBindings.length; i++) {
|
|
868
|
+
getBindingPaths(aDependentBindings[i]);
|
|
869
|
+
}
|
|
870
|
+
} else if (aNavigationPropertyPaths.indexOf(sPath) === -1) {
|
|
871
|
+
aNavigationPropertyPaths.push(sPath);
|
|
872
|
+
}
|
|
873
|
+
} else if (oBinding.isA("sap.ui.model.odata.v4.ODataListBinding")) {
|
|
874
|
+
if (aNavigationPropertyPaths.indexOf(sPath) === -1) {
|
|
875
|
+
aNavigationPropertyPaths.push(sPath);
|
|
876
|
+
}
|
|
877
|
+
} else if (oBinding.isA("sap.ui.model.odata.v4.ODataPropertyBinding")) {
|
|
878
|
+
if (aPropertyPaths.indexOf(sPath) === -1) {
|
|
879
|
+
aPropertyPaths.push(sPath);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
if (sContextPath) {
|
|
885
|
+
sMessagesPath = oMetaModel.getObject(sContextPath + "/@com.sap.vocabularies.Common.v1.Messages/$Path");
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// binding of the context must have $$PatchWithoutSideEffects true, this bound context may be needed to be fetched from the dependent binding
|
|
889
|
+
getBindingPaths(oBindingContext.getBinding());
|
|
890
|
+
|
|
891
|
+
let i;
|
|
892
|
+
for (i = 0; i < aNavigationPropertyPaths.length; i++) {
|
|
893
|
+
oSideEffects.TargetEntities.push({
|
|
894
|
+
$NavigationPropertyPath: aNavigationPropertyPaths[i]
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
oSideEffects.TargetProperties = aPropertyPaths;
|
|
898
|
+
if (sMessagesPath) {
|
|
899
|
+
oSideEffects.TargetProperties.push({
|
|
900
|
+
$PropertyPath: sMessagesPath
|
|
901
|
+
});
|
|
902
|
+
}
|
|
903
|
+
oSideEffectsService.requestSideEffects(oSideEffects.TargetEntities.concat(oSideEffects.TargetProperties), oBindingContext);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Gets the binding context of the page or the component.
|
|
908
|
+
*
|
|
909
|
+
* @returns {sap.ui.model.odata.v4.Context} The binding context
|
|
910
|
+
*
|
|
911
|
+
* @ui5-restricted
|
|
912
|
+
*/
|
|
913
|
+
_getBindingContext(): Context {
|
|
914
|
+
if (this._oPageComponent) {
|
|
915
|
+
return this._oPageComponent.getBindingContext() as Context;
|
|
916
|
+
} else {
|
|
917
|
+
return this._oView.getBindingContext() as Context;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Sets the binding context of the page or the component.
|
|
923
|
+
*
|
|
924
|
+
* @param {sap.ui.model.odata.v4.Context} oContext The binding context
|
|
925
|
+
*
|
|
926
|
+
* @ui5-restricted
|
|
927
|
+
*/
|
|
928
|
+
_setBindingContext(oContext: any) {
|
|
929
|
+
if (this._oPageComponent) {
|
|
930
|
+
this._oPageComponent.setBindingContext(oContext);
|
|
931
|
+
} else {
|
|
932
|
+
this._oView.setBindingContext(oContext);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* Gets the flexible column layout (FCL) level corresponding to the view (-1 if the app is not FCL).
|
|
938
|
+
*
|
|
939
|
+
* @returns {number} The level
|
|
940
|
+
*
|
|
941
|
+
* @ui5-restricted
|
|
942
|
+
*/
|
|
943
|
+
_getFCLLevel() {
|
|
944
|
+
return this._oTargetInformation.FCLLevel;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Switches between column and full-screen mode when FCL is used.
|
|
949
|
+
*
|
|
950
|
+
* @ui5-restricted
|
|
951
|
+
*/
|
|
952
|
+
|
|
953
|
+
@publicExtension()
|
|
954
|
+
@finalExtension()
|
|
955
|
+
switchFullScreen() {
|
|
956
|
+
const oSource = this.base.getView();
|
|
957
|
+
const oFCLHelperModel = oSource.getModel("fclhelper"),
|
|
958
|
+
bIsFullScreen = oFCLHelperModel.getProperty("/actionButtonsInfo/isFullScreen"),
|
|
959
|
+
sNextLayout = oFCLHelperModel.getProperty(
|
|
960
|
+
bIsFullScreen ? "/actionButtonsInfo/exitFullScreen" : "/actionButtonsInfo/fullScreen"
|
|
961
|
+
),
|
|
962
|
+
oRootViewController = (this._oAppComponent as any).getRootViewController();
|
|
963
|
+
|
|
964
|
+
const oContext = oRootViewController.getRightmostContext ? oRootViewController.getRightmostContext() : oSource.getBindingContext();
|
|
965
|
+
|
|
966
|
+
this.base._routing.navigateToContext(oContext, { sLayout: sNextLayout }).catch(function () {
|
|
967
|
+
Log.warning("cannot switch between column and fullscreen");
|
|
968
|
+
});
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/**
|
|
972
|
+
* Closes the column for the current view in a FCL.
|
|
973
|
+
*
|
|
974
|
+
* @ui5-restricted
|
|
975
|
+
*/
|
|
976
|
+
@publicExtension()
|
|
977
|
+
@extensible(OverrideExecution.Before)
|
|
978
|
+
closeColumn() {
|
|
979
|
+
const oSource = this.base.getView();
|
|
980
|
+
const oViewData = oSource.getViewData() as any;
|
|
981
|
+
const oContext = oSource.getBindingContext() as Context;
|
|
982
|
+
const base = this.base;
|
|
983
|
+
const oMetaModel = oContext.getModel().getMetaModel();
|
|
984
|
+
|
|
985
|
+
if (oViewData && oViewData.viewLevel === 1 && ModelHelper.isDraftSupported(oMetaModel, oContext.getPath())) {
|
|
986
|
+
CommonUtils.fnProcessDataLossOrDraftDiscardConfirmation(
|
|
987
|
+
function () {
|
|
988
|
+
base._routing.navigateBackFromContext(oContext, { noPreservationCache: true });
|
|
989
|
+
},
|
|
990
|
+
Function.prototype,
|
|
991
|
+
oContext,
|
|
992
|
+
oSource.getController(),
|
|
993
|
+
false
|
|
994
|
+
);
|
|
995
|
+
} else {
|
|
996
|
+
base._routing.navigateBackFromContext(oContext, { noPreservationCache: true });
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
export default InternalRouting;
|