@sapui5/sap.fe.core 1.97.0 → 1.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -4
- package/src/sap/fe/core/.library +1 -1
- package/src/sap/fe/core/AnnotationHelper.js +309 -405
- package/src/sap/fe/core/AnnotationHelper.ts +315 -0
- package/src/sap/fe/core/AppComponent.js +389 -397
- package/src/sap/fe/core/AppComponent.ts +403 -0
- package/src/sap/fe/core/AppStateHandler.js +198 -181
- package/src/sap/fe/core/AppStateHandler.ts +171 -0
- package/src/sap/fe/core/BaseController.js +83 -58
- package/src/sap/fe/core/BaseController.ts +68 -0
- package/src/sap/fe/core/BusyLocker.js +105 -121
- package/src/sap/fe/core/BusyLocker.ts +98 -0
- package/src/sap/fe/core/CommonUtils.js +2164 -2379
- package/src/sap/fe/core/CommonUtils.ts +2177 -0
- package/src/sap/fe/core/ExtensionAPI.js +279 -266
- package/src/sap/fe/core/ExtensionAPI.ts +250 -0
- package/src/sap/fe/core/PageController.js +218 -125
- package/src/sap/fe/core/PageController.ts +129 -0
- package/src/sap/fe/core/RouterProxy.js +924 -807
- package/src/sap/fe/core/RouterProxy.ts +840 -0
- package/src/sap/fe/core/Synchronization.js +41 -35
- package/src/sap/fe/core/Synchronization.ts +29 -0
- package/src/sap/fe/core/TemplateComponent.js +173 -155
- package/src/sap/fe/core/TemplateComponent.ts +173 -0
- package/src/sap/fe/core/TemplateModel.js +79 -54
- package/src/sap/fe/core/TemplateModel.ts +63 -0
- package/src/sap/fe/core/TransactionHelper.js +1560 -1579
- package/src/sap/fe/core/TransactionHelper.ts +1717 -0
- package/src/sap/fe/core/actions/collaboration/ActivitySync.js +392 -0
- package/src/sap/fe/core/actions/collaboration/ActivitySync.ts +355 -0
- package/src/sap/fe/core/actions/collaboration/CollaborationCommon.js +136 -0
- package/src/sap/fe/core/actions/collaboration/CollaborationCommon.ts +119 -0
- package/src/sap/fe/core/actions/collaboration/Manage.js +262 -0
- package/src/sap/fe/core/actions/collaboration/Manage.ts +244 -0
- package/src/sap/fe/core/actions/collaboration/ManageDialog.fragment.xml +103 -0
- package/src/sap/fe/core/actions/collaboration/UserDetails.fragment.xml +13 -0
- package/src/sap/fe/core/actions/draft.js +521 -581
- package/src/sap/fe/core/actions/draft.ts +566 -0
- package/src/sap/fe/core/actions/messageHandling.js +564 -511
- package/src/sap/fe/core/actions/messageHandling.ts +552 -0
- package/src/sap/fe/core/actions/nonDraft.js +17 -19
- package/src/sap/fe/core/actions/nonDraft.ts +12 -0
- package/src/sap/fe/core/actions/operations.js +1093 -1211
- package/src/sap/fe/core/actions/operations.ts +1192 -0
- package/src/sap/fe/core/actions/sticky.js +114 -104
- package/src/sap/fe/core/actions/sticky.ts +119 -0
- package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +70 -66
- package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.ts +65 -0
- package/src/sap/fe/core/controllerextensions/EditFlow.js +1594 -1701
- package/src/sap/fe/core/controllerextensions/EditFlow.ts +1672 -0
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +80 -54
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +61 -0
- package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +719 -505
- package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +783 -0
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +797 -813
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +803 -0
- package/src/sap/fe/core/controllerextensions/InternalRouting.js +1005 -973
- package/src/sap/fe/core/controllerextensions/InternalRouting.ts +978 -0
- package/src/sap/fe/core/controllerextensions/KPIManagement.js +530 -476
- package/src/sap/fe/core/controllerextensions/KPIManagement.ts +137 -46
- package/src/sap/fe/core/controllerextensions/MassEdit.js +144 -0
- package/src/sap/fe/core/controllerextensions/MassEdit.ts +156 -0
- package/src/sap/fe/core/controllerextensions/MessageHandler.js +234 -232
- package/src/sap/fe/core/controllerextensions/MessageHandler.ts +225 -0
- package/src/sap/fe/core/controllerextensions/PageReady.js +302 -337
- package/src/sap/fe/core/controllerextensions/PageReady.ts +23 -17
- package/src/sap/fe/core/controllerextensions/Paginator.js +189 -148
- package/src/sap/fe/core/controllerextensions/Paginator.ts +163 -0
- package/src/sap/fe/core/controllerextensions/Placeholder.js +158 -146
- package/src/sap/fe/core/controllerextensions/Placeholder.ts +151 -0
- package/src/sap/fe/core/controllerextensions/Routing.js +145 -106
- package/src/sap/fe/core/controllerextensions/Routing.ts +132 -0
- package/src/sap/fe/core/controllerextensions/RoutingListener.js +8 -6
- package/src/sap/fe/core/controllerextensions/RoutingListener.ts +3 -0
- package/src/sap/fe/core/controllerextensions/Share.js +220 -244
- package/src/sap/fe/core/controllerextensions/Share.ts +231 -0
- package/src/sap/fe/core/controllerextensions/SideEffects.js +593 -634
- package/src/sap/fe/core/controllerextensions/SideEffects.ts +29 -27
- package/src/sap/fe/core/controllerextensions/ViewState.js +789 -806
- package/src/sap/fe/core/controllerextensions/ViewState.ts +805 -0
- package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +4 -3
- package/src/sap/fe/core/controls/ActionPartial.fragment.xml +2 -2
- package/src/sap/fe/core/controls/CommandExecution.js +68 -66
- package/src/sap/fe/core/controls/CommandExecution.ts +72 -0
- package/src/sap/fe/core/controls/ConditionalWrapper.js +91 -75
- package/src/sap/fe/core/controls/ConditionalWrapper.ts +83 -0
- package/src/sap/fe/core/controls/CustomQuickViewPage.js +131 -125
- package/src/sap/fe/core/controls/CustomQuickViewPage.ts +126 -0
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +105 -110
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +101 -0
- package/src/sap/fe/core/controls/FieldWrapper.js +122 -140
- package/src/sap/fe/core/controls/FieldWrapper.ts +115 -0
- package/src/sap/fe/core/controls/FilterBar.js +163 -159
- package/src/sap/fe/core/controls/FilterBar.ts +143 -0
- package/src/sap/fe/core/controls/FormElementWrapper.js +46 -44
- package/src/sap/fe/core/controls/FormElementWrapper.ts +40 -0
- package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +38 -42
- package/src/sap/fe/core/controls/MultiValueParameterDelegate.ts +31 -0
- package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +2 -1
- package/src/sap/fe/core/controls/filterbar/FilterContainer.js +127 -116
- package/src/sap/fe/core/controls/filterbar/FilterContainer.ts +98 -0
- package/src/sap/fe/core/controls/filterbar/VisualFilter.js +242 -255
- package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +245 -0
- package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +151 -141
- package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +125 -0
- package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +336 -322
- package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +337 -0
- package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +106 -0
- package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +79 -0
- package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +70 -0
- package/src/sap/fe/core/converters/ConverterContext.js +348 -367
- package/src/sap/fe/core/converters/ConverterContext.ts +33 -19
- package/src/sap/fe/core/converters/ManifestSettings.js +12 -1
- package/src/sap/fe/core/converters/ManifestSettings.ts +16 -1
- package/src/sap/fe/core/converters/ManifestWrapper.js +354 -354
- package/src/sap/fe/core/converters/ManifestWrapper.ts +34 -6
- package/src/sap/fe/core/converters/MetaModelConverter.js +72 -9
- package/src/sap/fe/core/converters/MetaModelConverter.ts +75 -16
- package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
- package/src/sap/fe/core/converters/TemplateConverter.ts +4 -3
- package/src/sap/fe/core/converters/annotations/DataField.js +28 -14
- package/src/sap/fe/core/converters/annotations/DataField.ts +38 -14
- package/src/sap/fe/core/converters/common/AnnotationConverter.js +33 -21
- package/src/sap/fe/core/converters/controls/Common/Action.js +11 -2
- package/src/sap/fe/core/converters/controls/Common/Action.ts +8 -2
- package/src/sap/fe/core/converters/controls/Common/Chart.js +5 -3
- package/src/sap/fe/core/converters/controls/Common/Chart.ts +11 -3
- package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +3 -3
- package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +2 -2
- package/src/sap/fe/core/converters/controls/Common/Form.js +21 -11
- package/src/sap/fe/core/converters/controls/Common/Form.ts +28 -6
- package/src/sap/fe/core/converters/controls/Common/KPI.js +69 -4
- package/src/sap/fe/core/converters/controls/Common/KPI.ts +75 -2
- package/src/sap/fe/core/converters/controls/Common/Table.js +507 -408
- package/src/sap/fe/core/converters/controls/Common/Table.ts +618 -500
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +592 -0
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +718 -0
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +465 -59
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +462 -72
- package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +2 -2
- package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +1 -1
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +17 -9
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +24 -9
- package/src/sap/fe/core/converters/helpers/Aggregation.js +118 -121
- package/src/sap/fe/core/converters/helpers/Aggregation.ts +28 -5
- 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/IssueManager.js +7 -1
- package/src/sap/fe/core/converters/helpers/IssueManager.ts +6 -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/HeaderAndFooterAction.js +28 -7
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +23 -6
- package/src/sap/fe/core/converters/templates/ListReportConverter.js +20 -7
- package/src/sap/fe/core/converters/templates/ListReportConverter.ts +36 -14
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +7 -5
- package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +5 -1
- package/src/sap/fe/core/designtime/AppComponent.designtime.js +93 -90
- 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/CriticalityFormatter.js +1 -1
- package/src/sap/fe/core/formatters/CriticalityFormatter.ts +1 -1
- package/src/sap/fe/core/formatters/FPMFormatter.js +1 -1
- package/src/sap/fe/core/formatters/FPMFormatter.ts +4 -10
- package/src/sap/fe/core/formatters/KPIFormatter.js +1 -1
- package/src/sap/fe/core/formatters/KPIFormatter.ts +3 -1
- package/src/sap/fe/core/formatters/TableFormatter.js +91 -29
- package/src/sap/fe/core/formatters/TableFormatter.ts +94 -28
- package/src/sap/fe/core/formatters/ValueFormatter.js +30 -5
- package/src/sap/fe/core/formatters/ValueFormatter.ts +30 -7
- package/src/sap/fe/core/fpm/Component.js +51 -54
- package/src/sap/fe/core/fpm/Component.ts +48 -0
- package/src/sap/fe/core/helpers/AppStartupHelper.js +373 -0
- package/src/sap/fe/core/helpers/AppStartupHelper.ts +417 -0
- package/src/sap/fe/core/helpers/BindingExpression.js +489 -442
- package/src/sap/fe/core/helpers/BindingExpression.ts +486 -469
- package/src/sap/fe/core/helpers/ClassSupport.js +212 -76
- package/src/sap/fe/core/helpers/ClassSupport.ts +198 -71
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +64 -59
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +52 -0
- package/src/sap/fe/core/helpers/EditState.js +81 -84
- package/src/sap/fe/core/helpers/EditState.ts +81 -0
- package/src/sap/fe/core/helpers/ExcelFormatHelper.js +62 -48
- package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +49 -0
- package/src/sap/fe/core/helpers/FPMHelper.js +52 -56
- package/src/sap/fe/core/helpers/FPMHelper.ts +62 -0
- package/src/sap/fe/core/helpers/KeepAliveHelper.js +4 -5
- package/src/sap/fe/core/helpers/KeepAliveHelper.ts +10 -10
- package/src/sap/fe/core/helpers/MassEditHelper.js +604 -0
- package/src/sap/fe/core/helpers/MassEditHelper.ts +699 -0
- package/src/sap/fe/core/helpers/ModelHelper.js +253 -225
- package/src/sap/fe/core/helpers/ModelHelper.ts +250 -0
- package/src/sap/fe/core/helpers/PasteHelper.js +210 -132
- package/src/sap/fe/core/helpers/PasteHelper.ts +196 -0
- package/src/sap/fe/core/helpers/SemanticDateOperators.js +336 -313
- package/src/sap/fe/core/helpers/SemanticDateOperators.ts +334 -0
- package/src/sap/fe/core/helpers/SemanticKeyHelper.js +66 -67
- package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +73 -0
- package/src/sap/fe/core/helpers/StableIdHelper.js +4 -7
- package/src/sap/fe/core/helpers/StableIdHelper.ts +2 -6
- package/src/sap/fe/core/jsx-runtime/jsx.js +1 -1
- package/src/sap/fe/core/jsx-runtime/jsx.ts +1 -1
- package/src/sap/fe/core/library.js +427 -425
- package/src/sap/fe/core/library.support.js +23 -27
- 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 +64 -0
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +69 -0
- package/src/sap/fe/core/messagebundle.properties +78 -13
- package/src/sap/fe/core/messagebundle_ar.properties +58 -7
- package/src/sap/fe/core/messagebundle_bg.properties +58 -7
- package/src/sap/fe/core/messagebundle_ca.properties +58 -7
- package/src/sap/fe/core/messagebundle_cs.properties +59 -8
- package/src/sap/fe/core/messagebundle_cy.properties +58 -7
- package/src/sap/fe/core/messagebundle_da.properties +58 -7
- package/src/sap/fe/core/messagebundle_de.properties +58 -7
- package/src/sap/fe/core/messagebundle_el.properties +58 -7
- package/src/sap/fe/core/messagebundle_en.properties +57 -6
- package/src/sap/fe/core/messagebundle_en_GB.properties +57 -6
- package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +61 -6
- package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +58 -7
- package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +58 -7
- package/src/sap/fe/core/messagebundle_es.properties +58 -7
- package/src/sap/fe/core/messagebundle_es_MX.properties +58 -7
- package/src/sap/fe/core/messagebundle_et.properties +58 -7
- package/src/sap/fe/core/messagebundle_fi.properties +60 -9
- package/src/sap/fe/core/messagebundle_fr.properties +64 -13
- package/src/sap/fe/core/messagebundle_fr_CA.properties +59 -8
- package/src/sap/fe/core/messagebundle_hi.properties +58 -7
- package/src/sap/fe/core/messagebundle_hr.properties +58 -7
- package/src/sap/fe/core/messagebundle_hu.properties +59 -8
- package/src/sap/fe/core/messagebundle_id.properties +61 -10
- package/src/sap/fe/core/messagebundle_it.properties +58 -7
- package/src/sap/fe/core/messagebundle_iw.properties +58 -7
- package/src/sap/fe/core/messagebundle_ja.properties +58 -7
- package/src/sap/fe/core/messagebundle_kk.properties +58 -7
- package/src/sap/fe/core/messagebundle_ko.properties +58 -7
- package/src/sap/fe/core/messagebundle_lt.properties +58 -7
- package/src/sap/fe/core/messagebundle_lv.properties +59 -8
- package/src/sap/fe/core/messagebundle_ms.properties +58 -7
- package/src/sap/fe/core/messagebundle_nl.properties +58 -7
- package/src/sap/fe/core/messagebundle_no.properties +58 -7
- package/src/sap/fe/core/messagebundle_pl.properties +58 -7
- package/src/sap/fe/core/messagebundle_pt.properties +59 -8
- package/src/sap/fe/core/messagebundle_pt_PT.properties +58 -7
- package/src/sap/fe/core/messagebundle_ro.properties +58 -7
- package/src/sap/fe/core/messagebundle_ru.properties +58 -7
- package/src/sap/fe/core/messagebundle_sh.properties +58 -7
- package/src/sap/fe/core/messagebundle_sk.properties +58 -7
- package/src/sap/fe/core/messagebundle_sl.properties +58 -7
- package/src/sap/fe/core/messagebundle_sv.properties +59 -8
- package/src/sap/fe/core/messagebundle_th.properties +58 -7
- package/src/sap/fe/core/messagebundle_tr.properties +60 -9
- package/src/sap/fe/core/messagebundle_uk.properties +58 -7
- package/src/sap/fe/core/messagebundle_vi.properties +58 -7
- package/src/sap/fe/core/messagebundle_zh_CN.properties +58 -7
- package/src/sap/fe/core/messagebundle_zh_TW.properties +58 -7
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +45 -71
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +3 -1
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +231 -202
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +212 -0
- package/src/sap/fe/core/services/EnvironmentServiceFactory.js +67 -92
- package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +10 -6
- package/src/sap/fe/core/services/NavigationServiceFactory.js +351 -300
- package/src/sap/fe/core/services/NavigationServiceFactory.ts +313 -0
- package/src/sap/fe/core/services/ResourceModelServiceFactory.js +114 -81
- package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +83 -0
- package/src/sap/fe/core/services/RoutingServiceFactory.js +927 -1152
- package/src/sap/fe/core/services/RoutingServiceFactory.ts +898 -0
- package/src/sap/fe/core/services/ShellServicesFactory.js +649 -707
- package/src/sap/fe/core/services/ShellServicesFactory.ts +52 -15
- package/src/sap/fe/core/services/SideEffectsServiceFactory.js +569 -637
- package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +78 -102
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +429 -478
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +460 -0
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.js +10 -8
- package/src/sap/fe/core/services/view/TemplatingErrorPage.controller.ts +8 -0
- package/src/sap/fe/core/support/AnnotationIssue.support.js +15 -3
- package/src/sap/fe/core/support/AnnotationIssue.support.ts +16 -2
- package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.js +2 -2
- package/src/sap/fe/core/support/CollectionFacetUnsupportedLevel.support.ts +1 -1
- package/src/sap/fe/core/support/CommonHelper.js +1 -1
- package/src/sap/fe/core/support/CommonHelper.ts +1 -1
- package/src/sap/fe/core/support/Diagnostics.js +36 -48
- package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.js +38 -0
- package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.ts +18 -0
- package/src/sap/fe/core/templating/DataModelPathHelper.js +97 -127
- package/src/sap/fe/core/templating/DataModelPathHelper.ts +112 -135
- package/src/sap/fe/core/templating/DisplayModeFormatter.js +114 -0
- package/src/sap/fe/core/templating/DisplayModeFormatter.ts +86 -0
- package/src/sap/fe/core/templating/FieldControlHelper.js +8 -8
- package/src/sap/fe/core/templating/FieldControlHelper.ts +25 -7
- package/src/sap/fe/core/templating/FilterHelper.js +140 -78
- package/src/sap/fe/core/templating/FilterHelper.ts +149 -78
- package/src/sap/fe/core/templating/PropertyHelper.js +3 -3
- package/src/sap/fe/core/templating/PropertyHelper.ts +2 -2
- package/src/sap/fe/core/templating/UIFormatters.js +76 -135
- package/src/sap/fe/core/templating/UIFormatters.ts +76 -99
- package/src/sap/fe/core/type/Email.js +1 -1
- package/src/sap/fe/core/type/Email.ts +4 -6
- package/ui5.yaml +0 -3
- package/src/sap/fe/core/controls/filterbar.d.js +0 -8
- package/src/sap/fe/core/controls/filterbar.d.ts +0 -0
|
@@ -0,0 +1,1672 @@
|
|
|
1
|
+
import ControllerExtension from "sap/ui/core/mvc/ControllerExtension";
|
|
2
|
+
import OverrideExecution from "sap/ui/core/mvc/OverrideExecution";
|
|
3
|
+
import Log from "sap/base/Log";
|
|
4
|
+
import CommonUtils from "sap/fe/core/CommonUtils";
|
|
5
|
+
import BusyLocker from "sap/fe/core/BusyLocker";
|
|
6
|
+
import FELibrary from "sap/fe/core/library";
|
|
7
|
+
import ODataListBinding from "sap/ui/model/odata/v4/ODataListBinding";
|
|
8
|
+
import SemanticKeyHelper from "sap/fe/core/helpers/SemanticKeyHelper";
|
|
9
|
+
import EditState from "sap/fe/core/helpers/EditState";
|
|
10
|
+
import Message from "sap/ui/core/message/Message";
|
|
11
|
+
import coreLibrary from "sap/ui/core/library";
|
|
12
|
+
import ModelHelper, { InternalModelContext } from "sap/fe/core/helpers/ModelHelper";
|
|
13
|
+
import { Extensible, Final, Public, UI5Class } from "sap/fe/core/helpers/ClassSupport";
|
|
14
|
+
import ControllerExtensionMetadata from "sap/fe/core/controllerextensions/ControllerExtensionMetadata";
|
|
15
|
+
import PageController from "sap/fe/core/PageController";
|
|
16
|
+
import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
|
|
17
|
+
import Table from "sap/ui/mdc/Table";
|
|
18
|
+
import Context from "sap/ui/model/odata/v4/Context";
|
|
19
|
+
import ResourceBundle from "sap/base/i18n/ResourceBundle";
|
|
20
|
+
import Control from "sap/ui/core/Control";
|
|
21
|
+
import { send } from "sap/fe/core/actions/collaboration/ActivitySync";
|
|
22
|
+
import { Activity } from "sap/fe/core/actions/collaboration/CollaborationCommon";
|
|
23
|
+
import ODataModel from "sap/ui/model/odata/v4/ODataModel";
|
|
24
|
+
import FlexibleColumnLayout from "sap/f/FlexibleColumnLayout";
|
|
25
|
+
import NavContainer from "sap/m/NavContainer";
|
|
26
|
+
|
|
27
|
+
const CreationMode = FELibrary.CreationMode,
|
|
28
|
+
ProgrammingModel = FELibrary.ProgrammingModel,
|
|
29
|
+
Constants = FELibrary.Constants,
|
|
30
|
+
DraftStatus = FELibrary.DraftStatus,
|
|
31
|
+
EditMode = FELibrary.EditMode,
|
|
32
|
+
MessageType = coreLibrary.MessageType;
|
|
33
|
+
/**
|
|
34
|
+
* A controller extension offering hooks into the edit flow of the application
|
|
35
|
+
*
|
|
36
|
+
* @hideconstructor
|
|
37
|
+
* @public
|
|
38
|
+
* @since 1.90.0
|
|
39
|
+
*/
|
|
40
|
+
@UI5Class("sap.fe.core.controllerextensions.EditFlow", ControllerExtensionMetadata)
|
|
41
|
+
class EditFlow extends ControllerExtension {
|
|
42
|
+
private base!: PageController;
|
|
43
|
+
|
|
44
|
+
//////////////////////////////////////
|
|
45
|
+
// Public methods
|
|
46
|
+
//////////////////////////////////////
|
|
47
|
+
|
|
48
|
+
private fnDirtyStateProvider?: Function;
|
|
49
|
+
private fnHandleSessionTimeout?: Function;
|
|
50
|
+
private mPatchPromises?: any;
|
|
51
|
+
private _fnStickyDiscardAfterNavigation?: Function;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Creates a draft document for an existing active document.
|
|
55
|
+
*
|
|
56
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
57
|
+
* @param {object} oContext Context of the active document
|
|
58
|
+
* @returns {Promise} Promise resolves once the editable document is available
|
|
59
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#editDocument
|
|
60
|
+
* @public
|
|
61
|
+
* @since 1.90.0
|
|
62
|
+
*/
|
|
63
|
+
@Public
|
|
64
|
+
@Final
|
|
65
|
+
editDocument(oContext: Context): Promise<any> {
|
|
66
|
+
const bDraftNavigation = true;
|
|
67
|
+
const transactionHelper = this._getTransactionHelper();
|
|
68
|
+
|
|
69
|
+
return this.base.editFlow
|
|
70
|
+
.onBeforeEdit({ context: oContext })
|
|
71
|
+
.then(transactionHelper.editDocument.bind(transactionHelper, oContext, this.getView(), this._getMessageHandler()))
|
|
72
|
+
.then((oNewDocumentContext: any) => {
|
|
73
|
+
const sProgrammingModel = this._getProgrammingModel(oContext);
|
|
74
|
+
|
|
75
|
+
if (sProgrammingModel === ProgrammingModel.Sticky) {
|
|
76
|
+
this._getInternalModel().setProperty("/sessionOn", true);
|
|
77
|
+
}
|
|
78
|
+
if (oNewDocumentContext) {
|
|
79
|
+
this._setEditMode(EditMode.Editable, false);
|
|
80
|
+
this._getMessageHandler().showMessageDialog();
|
|
81
|
+
|
|
82
|
+
if (oNewDocumentContext !== oContext) {
|
|
83
|
+
return this._handleNewContext(oNewDocumentContext, true, false, bDraftNavigation, true).then(() => {
|
|
84
|
+
if (sProgrammingModel === ProgrammingModel.Sticky) {
|
|
85
|
+
// The stickyOn handler must be set after the navigation has been done,
|
|
86
|
+
// as the URL may change in the case of FCL
|
|
87
|
+
this._handleStickyOn(oNewDocumentContext);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
.catch(function(oError: any) {
|
|
94
|
+
Log.error("Error while editing the document", oError);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
@Public
|
|
98
|
+
@Final
|
|
99
|
+
deleteMultipleDocuments(aContexts: any, mParameters: any) {
|
|
100
|
+
if (mParameters) {
|
|
101
|
+
mParameters.beforeDeleteCallBack = this.base.editFlow.onBeforeDelete;
|
|
102
|
+
} else {
|
|
103
|
+
mParameters = {
|
|
104
|
+
beforeDeleteCallBack: this.base.editFlow.onBeforeDelete
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return (this.base.getView().getController() as PageController)._editFlow.deleteMultipleDocuments(aContexts, mParameters);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Updates the draft status and displays the error messages if there are errors during an update.
|
|
112
|
+
*
|
|
113
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
114
|
+
* @param {object} oContext Context of the updated field
|
|
115
|
+
* @param {object} oPromise Promise to determine when the update operation is completed. The promise should be resolved when the update operation is completed, so the draft status can be updated.
|
|
116
|
+
* @returns {Promise} Promise resolves once draft status has been updated
|
|
117
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#updateDocument
|
|
118
|
+
* @public
|
|
119
|
+
* @since 1.90.0
|
|
120
|
+
*/
|
|
121
|
+
@Public
|
|
122
|
+
@Final
|
|
123
|
+
updateDocument(oContext: object, oPromise: Promise<any>): Promise<void> {
|
|
124
|
+
const transactionHelper = this._getTransactionHelper(),
|
|
125
|
+
oBindingContext = this.getView().getBindingContext(),
|
|
126
|
+
bIsDraft = this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
|
|
127
|
+
|
|
128
|
+
this._getMessageHandler().removeTransitionMessages();
|
|
129
|
+
return this._syncTask(() => {
|
|
130
|
+
if (oBindingContext) {
|
|
131
|
+
transactionHelper.handleDocumentModifications();
|
|
132
|
+
EditState.setEditStateDirty();
|
|
133
|
+
|
|
134
|
+
if (bIsDraft) {
|
|
135
|
+
this._setDraftStatus(DraftStatus.Saving);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
this._getMessageHandler().removeTransitionMessages();
|
|
139
|
+
|
|
140
|
+
return oPromise
|
|
141
|
+
.then(
|
|
142
|
+
() => {
|
|
143
|
+
if (bIsDraft && oBindingContext) {
|
|
144
|
+
const oMetaModel = oBindingContext.getModel().getMetaModel() as ODataMetaModel,
|
|
145
|
+
sEntitySetName = (oMetaModel as any).getMetaContext(oBindingContext.getPath()).getObject("@sapui.name"),
|
|
146
|
+
aSemanticKeys = SemanticKeyHelper.getSemanticKeys(oMetaModel, sEntitySetName);
|
|
147
|
+
if (aSemanticKeys && aSemanticKeys.length) {
|
|
148
|
+
const oCurrentSemanticMapping = (this.base.getAppComponent() as any)
|
|
149
|
+
.getRoutingService()
|
|
150
|
+
.getLastSemanticMapping(),
|
|
151
|
+
sCurrentSemanticPath = oCurrentSemanticMapping && oCurrentSemanticMapping.semanticPath,
|
|
152
|
+
sChangedPath = SemanticKeyHelper.getSemanticPath(oBindingContext, true);
|
|
153
|
+
|
|
154
|
+
if (sCurrentSemanticPath !== sChangedPath) {
|
|
155
|
+
return this._handleNewContext(oBindingContext, true, false, true).then(() => {
|
|
156
|
+
this._setDraftStatus(DraftStatus.Saved);
|
|
157
|
+
});
|
|
158
|
+
} else {
|
|
159
|
+
this._setDraftStatus(DraftStatus.Saved);
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
this._setDraftStatus(DraftStatus.Saved);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
() => {
|
|
167
|
+
if (bIsDraft && oBindingContext) {
|
|
168
|
+
this._setDraftStatus(DraftStatus.Clear);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
)
|
|
172
|
+
.catch(function(oError: any) {
|
|
173
|
+
Log.error("Error while updating the document", oError);
|
|
174
|
+
})
|
|
175
|
+
.finally(() => {
|
|
176
|
+
this._getMessageHandler().showMessages();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Internal only params ---
|
|
182
|
+
// * @param {string} mParameters.creationMode The creation mode using one of the following:
|
|
183
|
+
// * Sync - the creation is triggered and once the document is created, the navigation is done
|
|
184
|
+
// * Async - the creation and the navigation to the instance are done in parallel
|
|
185
|
+
// * Deferred - the creation is done on the target page
|
|
186
|
+
// * CreationRow - The creation is done inline async so the user is not blocked
|
|
187
|
+
// mParameters.creationRow Instance of the creation row - (TODO: get rid but use list bindings only)
|
|
188
|
+
|
|
189
|
+
// eslint-disable-next-line jsdoc/require-param
|
|
190
|
+
/**
|
|
191
|
+
* Creates a new document.
|
|
192
|
+
*
|
|
193
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
194
|
+
* @param {sap.ui.model.odata.v4.ODataListBinding|string} vListBinding ODataListBinding object or the binding path for a temporary list binding
|
|
195
|
+
* @param {map} mInParameters Contains the following attributes:
|
|
196
|
+
* @param {string} mInParameters.creationMode The creation mode using one of the following:
|
|
197
|
+
* NewPage - the created document is shown in a new page, depending on whether metadata 'Sync', 'Async' or 'Deferred' is used
|
|
198
|
+
* Inline - The creation is done inline (in a table)
|
|
199
|
+
* External - The creation is done in a different application specified via the parameter 'outbound'
|
|
200
|
+
* @param {string} mInParameters.outbound The navigation target where the document is created in case of creationMode 'External'
|
|
201
|
+
* @param {boolean} mInParameters.createAtEnd Specifies if the new entry should be created at the top or bottom of a table in case of creationMode 'Inline'
|
|
202
|
+
* @returns {Promise} Promise resolves once the object has been created
|
|
203
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#createDocument
|
|
204
|
+
* @public
|
|
205
|
+
* @since 1.90.0
|
|
206
|
+
*/
|
|
207
|
+
@Public
|
|
208
|
+
@Final
|
|
209
|
+
createDocument(
|
|
210
|
+
vListBinding: ODataListBinding | string,
|
|
211
|
+
mInParameters: {
|
|
212
|
+
creationMode: string;
|
|
213
|
+
outbound?: string;
|
|
214
|
+
createAtEnd?: boolean;
|
|
215
|
+
}
|
|
216
|
+
): Promise<void> {
|
|
217
|
+
const transactionHelper = this._getTransactionHelper(),
|
|
218
|
+
oLockObject = this._getGlobalUIModel();
|
|
219
|
+
let oTable: Table;
|
|
220
|
+
let iCountTableItems = 0;
|
|
221
|
+
let mParameters: any = mInParameters;
|
|
222
|
+
const oResourceBundle = (this.getView().getController() as any).oResourceBundle;
|
|
223
|
+
const bShouldBusyLock =
|
|
224
|
+
!mParameters ||
|
|
225
|
+
(mParameters.creationMode !== CreationMode.Inline &&
|
|
226
|
+
mParameters.creationMode !== CreationMode.CreationRow &&
|
|
227
|
+
mParameters.creationMode !== CreationMode.External);
|
|
228
|
+
let oExecCustomValidation = Promise.resolve([]);
|
|
229
|
+
const oAppComponent = CommonUtils.getAppComponent(this.getView());
|
|
230
|
+
oAppComponent.getRouterProxy().removeIAppStateKey();
|
|
231
|
+
|
|
232
|
+
if (mParameters.creationMode === CreationMode.External) {
|
|
233
|
+
// Create by navigating to an external target
|
|
234
|
+
// TODO: Call appropriate function (currently using the same as for outbound chevron nav, and without any context - 3rd param)
|
|
235
|
+
return this._syncTask().then(() => {
|
|
236
|
+
const oController = this.getView().getController(),
|
|
237
|
+
sCreatePath = ModelHelper.getAbsoluteMetaPathForListBinding(this.getView(), vListBinding);
|
|
238
|
+
|
|
239
|
+
(oController as any).handlers.onChevronPressNavigateOutBound(oController, mParameters.outbound, undefined, sCreatePath);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (mParameters.creationMode === CreationMode.CreationRow && mParameters.creationRow) {
|
|
244
|
+
const oCreationRowObjects = mParameters.creationRow.getBindingContext().getObject();
|
|
245
|
+
delete oCreationRowObjects["@$ui5.context.isTransient"];
|
|
246
|
+
oTable = mParameters.creationRow.getParent();
|
|
247
|
+
oExecCustomValidation = transactionHelper.validateDocument(
|
|
248
|
+
oTable.getBindingContext(),
|
|
249
|
+
{
|
|
250
|
+
data: oCreationRowObjects,
|
|
251
|
+
customValidationFunction: (oTable.getCreationRow() as any).data("customValidationFunction")
|
|
252
|
+
},
|
|
253
|
+
this.base.getView()
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
// disableAddRowButtonForEmptyData is set to false in manifest converter (Table.ts) if customValidationFunction exists
|
|
257
|
+
if ((oTable.getCreationRow() as any).data("disableAddRowButtonForEmptyData") === "true") {
|
|
258
|
+
const oInternalModelContext = oTable.getBindingContext("internal") as InternalModelContext;
|
|
259
|
+
oInternalModelContext.setProperty("creationRowFieldValidity", {});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (mParameters.creationMode === CreationMode.Inline && mParameters.tableId) {
|
|
264
|
+
oTable = this.getView().byId(mParameters.tableId) as Table;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @param {sap.ui.model.odata.v4.ODataListBinding} oListBinding
|
|
269
|
+
* @param {object} oCreationPromise
|
|
270
|
+
*/
|
|
271
|
+
const handleSideEffects = (oListBinding: any, oCreationPromise: Promise<Context>) => {
|
|
272
|
+
oCreationPromise
|
|
273
|
+
.then(function(oNewContext: any) {
|
|
274
|
+
// transient contexts are reliably removed once oNewContext.created() is resolved
|
|
275
|
+
return oNewContext.created();
|
|
276
|
+
})
|
|
277
|
+
.then(() => {
|
|
278
|
+
const oBindingContext = this.getView().getBindingContext() as Context;
|
|
279
|
+
// if there are transient contexts, we must avoid requesting side effects
|
|
280
|
+
// this is avoid a potential list refresh, there could be a side effect that refreshes the list binding
|
|
281
|
+
// if list binding is refreshed, transient contexts might be lost
|
|
282
|
+
if (!CommonUtils.hasTransientContext(oListBinding)) {
|
|
283
|
+
const oAppComponent = CommonUtils.getAppComponent(this.getView());
|
|
284
|
+
oAppComponent
|
|
285
|
+
.getSideEffectsService()
|
|
286
|
+
.requestSideEffectsForNavigationProperty(oListBinding.getPath(), oBindingContext);
|
|
287
|
+
}
|
|
288
|
+
})
|
|
289
|
+
.catch(function(oError: any) {
|
|
290
|
+
Log.error("Error while creating the document", oError);
|
|
291
|
+
});
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* @param {Array} aValidationMessages Error messages from custom validation function
|
|
296
|
+
*/
|
|
297
|
+
const createCustomValidationMessages = (aValidationMessages: any[]) => {
|
|
298
|
+
const sCustomValidationFunction = oTable && (oTable.getCreationRow() as any).data("customValidationFunction");
|
|
299
|
+
const mCustomValidity = oTable && oTable.getBindingContext("internal")?.getProperty("creationRowCustomValidity");
|
|
300
|
+
const oMessageManager = sap.ui.getCore().getMessageManager();
|
|
301
|
+
const aCustomMessages: any[] = [];
|
|
302
|
+
let oFieldControl;
|
|
303
|
+
let sTarget: string;
|
|
304
|
+
|
|
305
|
+
// Remove existing CustomValidation message
|
|
306
|
+
oMessageManager
|
|
307
|
+
.getMessageModel()
|
|
308
|
+
.getData()
|
|
309
|
+
.forEach(function(oMessage: any) {
|
|
310
|
+
if (oMessage.code === sCustomValidationFunction) {
|
|
311
|
+
oMessageManager.removeMessages(oMessage);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
aValidationMessages.forEach((oValidationMessage: any) => {
|
|
316
|
+
// Handle Bound CustomValidation message
|
|
317
|
+
if (oValidationMessage.messageTarget) {
|
|
318
|
+
oFieldControl = sap.ui.getCore().getControl(mCustomValidity[oValidationMessage.messageTarget].fieldId) as Control;
|
|
319
|
+
sTarget = oFieldControl.getBindingContext()?.getPath() + "/" + oFieldControl.getBindingPath("value");
|
|
320
|
+
// Add validation message if still not exists
|
|
321
|
+
if (
|
|
322
|
+
oMessageManager
|
|
323
|
+
.getMessageModel()
|
|
324
|
+
.getData()
|
|
325
|
+
.filter(function(oMessage: any) {
|
|
326
|
+
return oMessage.target === sTarget;
|
|
327
|
+
}).length === 0
|
|
328
|
+
) {
|
|
329
|
+
oMessageManager.addMessages(
|
|
330
|
+
new Message({
|
|
331
|
+
message: oValidationMessage.messageText,
|
|
332
|
+
processor: this.getView().getModel(),
|
|
333
|
+
type: MessageType.Error,
|
|
334
|
+
code: sCustomValidationFunction,
|
|
335
|
+
technical: false,
|
|
336
|
+
persistent: false,
|
|
337
|
+
target: sTarget
|
|
338
|
+
})
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
// Add controlId in order to get the focus handling of the error popover runable
|
|
342
|
+
const aExistingValidationMessages = oMessageManager
|
|
343
|
+
.getMessageModel()
|
|
344
|
+
.getData()
|
|
345
|
+
.filter(function(oMessage: any) {
|
|
346
|
+
return oMessage.target === sTarget;
|
|
347
|
+
});
|
|
348
|
+
aExistingValidationMessages[0].addControlId(mCustomValidity[oValidationMessage.messageTarget].fieldId);
|
|
349
|
+
|
|
350
|
+
// Handle Unbound CustomValidation message
|
|
351
|
+
} else {
|
|
352
|
+
aCustomMessages.push({
|
|
353
|
+
code: sCustomValidationFunction,
|
|
354
|
+
text: oValidationMessage.messageText,
|
|
355
|
+
persistent: true,
|
|
356
|
+
type: MessageType.Error
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
if (aCustomMessages.length > 0) {
|
|
362
|
+
this._getMessageHandler().showMessageDialog({
|
|
363
|
+
customMessages: aCustomMessages
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
bShouldBusyLock && BusyLocker.lock(oLockObject);
|
|
369
|
+
return this._syncTask(oExecCustomValidation)
|
|
370
|
+
.then((aValidationMessages: any) => {
|
|
371
|
+
if (aValidationMessages.length > 0) {
|
|
372
|
+
createCustomValidationMessages(aValidationMessages);
|
|
373
|
+
Log.error("Custom Validation failed");
|
|
374
|
+
// if custom validation fails, we leave the method immediately
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
let sProgrammingModel: string;
|
|
379
|
+
let oListBinding: any;
|
|
380
|
+
|
|
381
|
+
mParameters = mParameters || {};
|
|
382
|
+
|
|
383
|
+
if (vListBinding && typeof vListBinding === "object") {
|
|
384
|
+
// we already get a list binding use this one
|
|
385
|
+
oListBinding = vListBinding;
|
|
386
|
+
} else if (typeof vListBinding === "string") {
|
|
387
|
+
oListBinding = new (ODataListBinding as any)(this.getView().getModel(), vListBinding);
|
|
388
|
+
mParameters.creationMode = CreationMode.Sync;
|
|
389
|
+
delete mParameters.createAtEnd;
|
|
390
|
+
} else {
|
|
391
|
+
throw new Error("Binding object or path expected");
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const oModel = oListBinding.getModel();
|
|
395
|
+
iCountTableItems = oListBinding.iMaxLength || 0;
|
|
396
|
+
const sCreationMode = mParameters.creationMode;
|
|
397
|
+
|
|
398
|
+
return Promise.resolve(this._getProgrammingModel(oListBinding))
|
|
399
|
+
.then((programmingModel: any) => {
|
|
400
|
+
sProgrammingModel = programmingModel;
|
|
401
|
+
if (sCreationMode && sCreationMode !== CreationMode.NewPage) {
|
|
402
|
+
// use the passed creation mode
|
|
403
|
+
return sCreationMode;
|
|
404
|
+
} else {
|
|
405
|
+
const oMetaModel = oModel.getMetaModel();
|
|
406
|
+
// NewAction is not yet supported for NavigationProperty collection
|
|
407
|
+
if (!oListBinding.isRelative()) {
|
|
408
|
+
const sPath = oListBinding.getPath(),
|
|
409
|
+
// if NewAction with parameters is present, then creation is 'Deferred'
|
|
410
|
+
// in the absence of NewAction or NewAction with parameters, creation is async
|
|
411
|
+
sNewAction =
|
|
412
|
+
sProgrammingModel === ProgrammingModel.Draft
|
|
413
|
+
? oMetaModel.getObject(sPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction")
|
|
414
|
+
: oMetaModel.getObject(
|
|
415
|
+
sPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction"
|
|
416
|
+
);
|
|
417
|
+
if (sNewAction) {
|
|
418
|
+
const aParameters = oMetaModel.getObject("/" + sNewAction + "/@$ui5.overload/0/$Parameter") || [];
|
|
419
|
+
// binding parameter (eg: _it) is not considered
|
|
420
|
+
if (aParameters.length > 1) {
|
|
421
|
+
return CreationMode.Deferred;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
const sMetaPath = oMetaModel.getMetaPath(oListBinding.getHeaderContext().getPath());
|
|
426
|
+
const aNonComputedVisibleKeyFields = CommonUtils.getNonComputedVisibleFields(
|
|
427
|
+
oMetaModel,
|
|
428
|
+
sMetaPath,
|
|
429
|
+
this.getView()
|
|
430
|
+
);
|
|
431
|
+
if (aNonComputedVisibleKeyFields.length > 0) {
|
|
432
|
+
return CreationMode.Deferred;
|
|
433
|
+
}
|
|
434
|
+
return CreationMode.Async;
|
|
435
|
+
}
|
|
436
|
+
})
|
|
437
|
+
.then((sCreationMode: any) => {
|
|
438
|
+
let oCreation: any;
|
|
439
|
+
let mArgs: any;
|
|
440
|
+
const oCreationRow = mParameters.creationRow;
|
|
441
|
+
let oCreationRowContext: any;
|
|
442
|
+
let oValidationCheck = Promise.resolve();
|
|
443
|
+
let oPayload: any;
|
|
444
|
+
let sMetaPath: string;
|
|
445
|
+
const oMetaModel = oModel.getMetaModel();
|
|
446
|
+
const oRoutingListener = this._getRoutingListener();
|
|
447
|
+
|
|
448
|
+
if (sCreationMode !== CreationMode.Deferred) {
|
|
449
|
+
if (sCreationMode === CreationMode.CreationRow) {
|
|
450
|
+
oCreationRowContext = oCreationRow.getBindingContext();
|
|
451
|
+
sMetaPath = oMetaModel.getMetaPath(oCreationRowContext.getPath());
|
|
452
|
+
// prefill data from creation row
|
|
453
|
+
oPayload = oCreationRowContext.getObject();
|
|
454
|
+
mParameters.data = {};
|
|
455
|
+
Object.keys(oPayload).forEach(function(sPropertyPath: string) {
|
|
456
|
+
const oProperty = oMetaModel.getObject(sMetaPath + "/" + sPropertyPath);
|
|
457
|
+
// ensure navigation properties are not part of the payload, deep create not supported
|
|
458
|
+
if (oProperty && oProperty.$kind === "NavigationProperty") {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
mParameters.data[sPropertyPath] = oPayload[sPropertyPath];
|
|
462
|
+
});
|
|
463
|
+
oValidationCheck = this._checkForValidationErrors(/*oCreationRowContext*/);
|
|
464
|
+
}
|
|
465
|
+
if (sCreationMode === CreationMode.CreationRow || sCreationMode === CreationMode.Inline) {
|
|
466
|
+
mParameters.keepTransientContextOnFailed = false; // currently not fully supported
|
|
467
|
+
// busy handling shall be done locally only
|
|
468
|
+
mParameters.busyMode = "Local";
|
|
469
|
+
|
|
470
|
+
// take care on message handling, draft indicator (in case of draft)
|
|
471
|
+
// Attach the create sent and create completed event to the object page binding so that we can react
|
|
472
|
+
this._handleCreateEvents(oListBinding);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
oCreation = oValidationCheck.then(() => {
|
|
476
|
+
if (!mParameters.parentControl) {
|
|
477
|
+
mParameters.parentControl = this.getView();
|
|
478
|
+
}
|
|
479
|
+
mParameters.beforeCreateCallBack = this.base.editFlow.onBeforeCreate;
|
|
480
|
+
return transactionHelper.createDocument(
|
|
481
|
+
oListBinding,
|
|
482
|
+
mParameters,
|
|
483
|
+
oResourceBundle,
|
|
484
|
+
this._getMessageHandler(),
|
|
485
|
+
false,
|
|
486
|
+
this.getView()
|
|
487
|
+
);
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
let oNavigation;
|
|
492
|
+
switch (sCreationMode) {
|
|
493
|
+
case CreationMode.Deferred:
|
|
494
|
+
oNavigation = oRoutingListener.navigateForwardToContext(oListBinding, {
|
|
495
|
+
bDeferredContext: true,
|
|
496
|
+
editable: true,
|
|
497
|
+
bForceFocus: true
|
|
498
|
+
});
|
|
499
|
+
break;
|
|
500
|
+
case CreationMode.Async:
|
|
501
|
+
oNavigation = oRoutingListener.navigateForwardToContext(oListBinding, {
|
|
502
|
+
asyncContext: oCreation,
|
|
503
|
+
editable: true,
|
|
504
|
+
bForceFocus: true
|
|
505
|
+
});
|
|
506
|
+
break;
|
|
507
|
+
case CreationMode.Sync:
|
|
508
|
+
mArgs = {
|
|
509
|
+
editable: true,
|
|
510
|
+
bForceFocus: true
|
|
511
|
+
};
|
|
512
|
+
if (sProgrammingModel == ProgrammingModel.Sticky || mParameters.createAction) {
|
|
513
|
+
mArgs.transient = true;
|
|
514
|
+
}
|
|
515
|
+
oNavigation = oCreation.then(function(oNewDocumentContext: any) {
|
|
516
|
+
if (!oNewDocumentContext) {
|
|
517
|
+
const oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core") as ResourceBundle;
|
|
518
|
+
return oRoutingListener.navigateToMessagePage(
|
|
519
|
+
oResourceBundle.getText("C_COMMON_SAPFE_DATA_RECEIVED_ERROR"),
|
|
520
|
+
{
|
|
521
|
+
title: oResourceBundle.getText("C_COMMON_SAPFE_ERROR"),
|
|
522
|
+
description: oResourceBundle.getText("C_EDITFLOW_SAPFE_CREATION_FAILED_DESCRIPTION")
|
|
523
|
+
}
|
|
524
|
+
);
|
|
525
|
+
} else {
|
|
526
|
+
return oRoutingListener.navigateForwardToContext(oNewDocumentContext, mArgs);
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
break;
|
|
530
|
+
case CreationMode.Inline:
|
|
531
|
+
handleSideEffects(oListBinding, oCreation);
|
|
532
|
+
this._syncTask(oCreation);
|
|
533
|
+
break;
|
|
534
|
+
case CreationMode.CreationRow:
|
|
535
|
+
// the creation row shall be cleared once the validation check was successful and
|
|
536
|
+
// therefore the POST can be sent async to the backend
|
|
537
|
+
oNavigation = oValidationCheck
|
|
538
|
+
.then(function() {
|
|
539
|
+
const oCreationRowListBinding = oCreationRowContext.getBinding();
|
|
540
|
+
|
|
541
|
+
if (!mParameters.bSkipSideEffects) {
|
|
542
|
+
handleSideEffects(oListBinding, oCreation);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
const oNewTransientContext = oCreationRowListBinding.create();
|
|
546
|
+
oCreationRow.setBindingContext(oNewTransientContext);
|
|
547
|
+
|
|
548
|
+
// this is needed to avoid console errors TO be checked with model colleagues
|
|
549
|
+
oNewTransientContext.created().catch(function() {
|
|
550
|
+
Log.trace("transient fast creation context deleted");
|
|
551
|
+
});
|
|
552
|
+
return oCreationRowContext.delete("$direct");
|
|
553
|
+
})
|
|
554
|
+
.catch((oError: any) => {
|
|
555
|
+
// Reset busy indicator after a validation error
|
|
556
|
+
if (BusyLocker.isLocked(this.getView().getModel("ui"))) {
|
|
557
|
+
BusyLocker.unlock(this.getView().getModel("ui"));
|
|
558
|
+
}
|
|
559
|
+
Log.error("CreationRow navigation error: ", oError);
|
|
560
|
+
});
|
|
561
|
+
break;
|
|
562
|
+
default:
|
|
563
|
+
oNavigation = Promise.reject("Unhandled creationMode " + sCreationMode);
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (sProgrammingModel === ProgrammingModel.Sticky) {
|
|
568
|
+
this._getInternalModel().setProperty("/sessionOn", true);
|
|
569
|
+
}
|
|
570
|
+
const bIsNewPageCreation =
|
|
571
|
+
mParameters.creationMode !== CreationMode.CreationRow && mParameters.creationMode !== CreationMode.Inline;
|
|
572
|
+
if (oCreation) {
|
|
573
|
+
return Promise.all([oCreation, oNavigation])
|
|
574
|
+
.then((aParams: [any, any]) => {
|
|
575
|
+
if (bIsNewPageCreation) {
|
|
576
|
+
this._setEditMode(EditMode.Editable, bIsNewPageCreation);
|
|
577
|
+
} else {
|
|
578
|
+
this._setEditMode(EditMode.Editable);
|
|
579
|
+
}
|
|
580
|
+
const oNewDocumentContext = aParams[0];
|
|
581
|
+
if (oNewDocumentContext) {
|
|
582
|
+
EditState.setEditStateDirty();
|
|
583
|
+
send(this.getView(), Activity.Create, oNewDocumentContext);
|
|
584
|
+
if (sProgrammingModel === ProgrammingModel.Sticky) {
|
|
585
|
+
this._handleStickyOn(oNewDocumentContext);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
})
|
|
589
|
+
.catch(function(oError: any) {
|
|
590
|
+
if (oError && (oError.navigateBackFromTransientState || oError == Constants.CancelActionDialog)) {
|
|
591
|
+
oRoutingListener.navigateBackFromTransientState();
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
return Promise.reject(oError);
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
})
|
|
599
|
+
.finally(function() {
|
|
600
|
+
if (oTable && oTable.isA("sap.ui.mdc.Table")) {
|
|
601
|
+
const fnFocusOrScroll =
|
|
602
|
+
mParameters.creationMode === CreationMode.Inline ? oTable.focusRow.bind(oTable) : oTable.scrollToIndex.bind(oTable);
|
|
603
|
+
oTable.getRowBinding().attachEventOnce("change", function() {
|
|
604
|
+
switch (mParameters.createAtEnd) {
|
|
605
|
+
case true:
|
|
606
|
+
if (oTable.data("tableType") === "ResponsiveTable" && oTable.getThreshold()) {
|
|
607
|
+
fnFocusOrScroll(oTable.getThreshold(), true);
|
|
608
|
+
} else {
|
|
609
|
+
fnFocusOrScroll(iCountTableItems, true);
|
|
610
|
+
}
|
|
611
|
+
break;
|
|
612
|
+
case false:
|
|
613
|
+
fnFocusOrScroll(0, true);
|
|
614
|
+
break;
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
bShouldBusyLock && BusyLocker.unlock(oLockObject);
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* This function can be used to intercept the 'Save' action. You can execute custom coding in this function.
|
|
624
|
+
* The framework waits for the returned promise to be resolved before continuing the 'Save' action.
|
|
625
|
+
* If you reject the promise, the 'Save' action is stopped and the user stays in edit mode.
|
|
626
|
+
*
|
|
627
|
+
* This function is meant to be individually overridden by consuming controllers, but not to be called directly.
|
|
628
|
+
* The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
|
|
629
|
+
* @param {object} mParameters Object containing the parameters passed to onBeforeSave
|
|
630
|
+
* @param {sap.ui.model.odata.v4.Context} mParameters.context Page context that is going to be saved.
|
|
631
|
+
* @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Save' action is triggered. If rejected, the 'Save' action is not triggered and the user stays in edit mode.
|
|
632
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
633
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#onBeforeSave
|
|
634
|
+
* @public
|
|
635
|
+
* @experimental As of version 1.90.0
|
|
636
|
+
* @since 1.90.0
|
|
637
|
+
*/
|
|
638
|
+
@Public
|
|
639
|
+
@Extensible(OverrideExecution.After)
|
|
640
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
641
|
+
onBeforeSave(mParameters?: { context?: Context }): Promise<void> {
|
|
642
|
+
// to be overridden
|
|
643
|
+
return Promise.resolve();
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* This function can be used to intercept the 'Create' action. You can execute custom coding in this function.
|
|
647
|
+
* The framework waits for the returned promise to be resolved before continuing the 'Create' action.
|
|
648
|
+
* If you reject the promise, the 'Create' action is stopped.
|
|
649
|
+
*
|
|
650
|
+
* This function is meant to be individually overridden by consuming controllers, but not to be called directly.
|
|
651
|
+
* The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
|
|
652
|
+
* @param {map} mParameters Object containing the parameters passed to onBeforeCreate
|
|
653
|
+
* @param {string} mParameters.contextPath Path pointing to the context on which Create action is triggered
|
|
654
|
+
* @param {Array} mParameters.createParameters Array of values that are filled in the Action Parameter Dialog
|
|
655
|
+
* @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Create' action is triggered. If rejected, the 'Create' action is not triggered.
|
|
656
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
657
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#onBeforeCreate
|
|
658
|
+
* @public
|
|
659
|
+
* @experimental As of version 1.98.0
|
|
660
|
+
* @since 1.98.0
|
|
661
|
+
*/
|
|
662
|
+
@Public
|
|
663
|
+
@Extensible(OverrideExecution.After)
|
|
664
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
665
|
+
onBeforeCreate(mParameters?: { contextPath?: string; createParameters?: any[] }): Promise<void> {
|
|
666
|
+
// to be overridden
|
|
667
|
+
return Promise.resolve();
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* This function can be used to intercept the 'Edit' action. You can execute custom coding in this function.
|
|
671
|
+
* The framework waits for the returned promise to be resolved before continuing the 'Edit' action.
|
|
672
|
+
* If you reject the promise, the 'Edit' action is stopped and the user stays in display mode.
|
|
673
|
+
*
|
|
674
|
+
* This function is meant to be individually overridden by consuming controllers, but not to be called directly.
|
|
675
|
+
* The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
|
|
676
|
+
* @param {object} mParameters Object containing the parameters passed to onBeforeEdit
|
|
677
|
+
* @param {sap.ui.model.odata.v4.Context} mParameters.context Page context that is going to be edited.
|
|
678
|
+
* @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Edit' action is triggered. If rejected, the 'Edit' action is not triggered and the user stays in display mode.
|
|
679
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
680
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#onBeforeEdit
|
|
681
|
+
* @public
|
|
682
|
+
* @experimental As of version 1.98.0
|
|
683
|
+
* @since 1.98.0
|
|
684
|
+
*/
|
|
685
|
+
@Public
|
|
686
|
+
@Extensible(OverrideExecution.After)
|
|
687
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
688
|
+
onBeforeEdit(mParameters?: { context?: Context }): Promise<void> {
|
|
689
|
+
// to be overridden
|
|
690
|
+
return Promise.resolve();
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* This function can be used to intercept the 'Discard' action. You can execute custom coding in this function.
|
|
694
|
+
* The framework waits for the returned promise to be resolved before continuing the 'Discard' action.
|
|
695
|
+
* If you reject the promise, the 'Discard' action is stopped and the user stays in edit mode.
|
|
696
|
+
*
|
|
697
|
+
* This function is meant to be individually overridden by consuming controllers, but not to be called directly.
|
|
698
|
+
* The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
|
|
699
|
+
* @param {object} mParameters Object containing the parameters passed to onBeforeDiscard
|
|
700
|
+
* @param {sap.ui.model.odata.v4.Context} mParameters.context Page context that is going to be discarded.
|
|
701
|
+
* @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Discard' action is triggered. If rejected, the 'Discard' action is not triggered and the user stays in edit mode.
|
|
702
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
703
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#onBeforeDiscard
|
|
704
|
+
* @public
|
|
705
|
+
* @experimental As of version 1.98.0
|
|
706
|
+
* @since 1.98.0
|
|
707
|
+
*/
|
|
708
|
+
@Public
|
|
709
|
+
@Extensible(OverrideExecution.After)
|
|
710
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
711
|
+
onBeforeDiscard(mParameters?: { context?: Context }): Promise<void> {
|
|
712
|
+
// to be overridden
|
|
713
|
+
return Promise.resolve();
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* This function can be used to intercept the 'Delete' action. You can execute custom coding in this function.
|
|
717
|
+
* The framework waits for the returned promise to be resolved before continuing the 'Delete' action.
|
|
718
|
+
* If you reject the promise, the 'Delete' action is stopped.
|
|
719
|
+
*
|
|
720
|
+
* This function is meant to be individually overridden by consuming controllers, but not to be called directly.
|
|
721
|
+
* The override execution is: {@link sap.ui.core.mvc.OverrideExecution.After}.
|
|
722
|
+
* @param {object} mParameters Object containing the parameters passed to onBeforeDelete
|
|
723
|
+
* @param {Array} mParameters.contexts An array of contexts that are going to be deleted
|
|
724
|
+
* @returns {Promise} A promise to be returned by the overridden method. If resolved, the 'Delete' action is triggered. If rejected, the 'Delete' action is not triggered.
|
|
725
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
726
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#onBeforeDelete
|
|
727
|
+
* @public
|
|
728
|
+
* @experimental As of version 1.98.0
|
|
729
|
+
* @since 1.98.0
|
|
730
|
+
*/
|
|
731
|
+
@Public
|
|
732
|
+
@Extensible(OverrideExecution.After)
|
|
733
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
734
|
+
onBeforeDelete(mParameters?: { contexts?: Context[] }): Promise<void> {
|
|
735
|
+
// to be overridden
|
|
736
|
+
return Promise.resolve();
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// Internal only params ---
|
|
740
|
+
// @param {boolean} mParameters.bExecuteSideEffectsOnError Indicates whether SideEffects need to be ignored when user clicks on Save during an Inline creation
|
|
741
|
+
// @param {object} mParameters.bindings List bindings of the tables in the view.
|
|
742
|
+
// Both of the above parameters are for the same purpose. User can enter some information in the creation row(s) but does not 'Add row', instead clicks Save.
|
|
743
|
+
// There can be more than one in the view.
|
|
744
|
+
|
|
745
|
+
// eslint-disable-next-line jsdoc/require-param
|
|
746
|
+
/**
|
|
747
|
+
* Saves a new document after checking it.
|
|
748
|
+
*
|
|
749
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
750
|
+
* @param {object} oContext Context of the editable document
|
|
751
|
+
* @returns {Promise} Promise resolves once save is complete
|
|
752
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#saveDocument
|
|
753
|
+
* @public
|
|
754
|
+
* @since 1.90.0
|
|
755
|
+
*/
|
|
756
|
+
@Public
|
|
757
|
+
@Final
|
|
758
|
+
saveDocument(oContext: Context, mParameters: any): Promise<void> {
|
|
759
|
+
mParameters = mParameters || {};
|
|
760
|
+
const bExecuteSideEffectsOnError = mParameters.bExecuteSideEffectsOnError || undefined;
|
|
761
|
+
const bDraftNavigation = true;
|
|
762
|
+
const transactionHelper = this._getTransactionHelper();
|
|
763
|
+
const oResourceBundle = (this.getView().getController() as any).oResourceBundle;
|
|
764
|
+
const aBindings = mParameters.bindings;
|
|
765
|
+
// first of all wait until all key-match-requests are done
|
|
766
|
+
return (
|
|
767
|
+
this._syncTask()
|
|
768
|
+
// submit any open changes if there any (although there are validation/parse errors)
|
|
769
|
+
.then(this._submitOpenChanges.bind(this, oContext))
|
|
770
|
+
// check if there are any validation/parse errors
|
|
771
|
+
.then(this._checkForValidationErrors.bind(this, oContext))
|
|
772
|
+
.then(this.base.editFlow.onBeforeSave.bind(this, { context: oContext }))
|
|
773
|
+
// and finally if all user changes are submitted and valid save the document
|
|
774
|
+
.then(
|
|
775
|
+
transactionHelper.saveDocument.bind(
|
|
776
|
+
transactionHelper,
|
|
777
|
+
oContext,
|
|
778
|
+
oResourceBundle,
|
|
779
|
+
bExecuteSideEffectsOnError,
|
|
780
|
+
aBindings,
|
|
781
|
+
this._getMessageHandler()
|
|
782
|
+
)
|
|
783
|
+
)
|
|
784
|
+
.then((oActiveDocumentContext: any) => {
|
|
785
|
+
const sProgrammingModel = this._getProgrammingModel(oContext);
|
|
786
|
+
|
|
787
|
+
this._removeContextsFromPages();
|
|
788
|
+
if (sProgrammingModel === ProgrammingModel.Sticky) {
|
|
789
|
+
this._getInternalModel().setProperty("/sessionOn", false);
|
|
790
|
+
this._handleStickyOff(/*oContext*/);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
send(this.getView(), Activity.Activate, oActiveDocumentContext);
|
|
794
|
+
|
|
795
|
+
this._setEditMode(EditMode.Display, false);
|
|
796
|
+
this._getMessageHandler().showMessageDialog();
|
|
797
|
+
|
|
798
|
+
if (oActiveDocumentContext !== oContext) {
|
|
799
|
+
this._handleNewContext(oActiveDocumentContext, false, false, bDraftNavigation, true);
|
|
800
|
+
}
|
|
801
|
+
})
|
|
802
|
+
.catch(function(oError: any) {
|
|
803
|
+
Log.error("Error while saving the document", oError);
|
|
804
|
+
return Promise.reject(oError);
|
|
805
|
+
})
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
@Public
|
|
809
|
+
@Final
|
|
810
|
+
toggleDraftActive(oContext: any) {
|
|
811
|
+
const oContextData = oContext.getObject();
|
|
812
|
+
let bEditable: boolean;
|
|
813
|
+
const bIsDraft = oContext && this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
|
|
814
|
+
const oToggleContext = oContext
|
|
815
|
+
.getModel()
|
|
816
|
+
.bindContext(oContext.getPath() + "/SiblingEntity")
|
|
817
|
+
.getBoundContext();
|
|
818
|
+
|
|
819
|
+
//toggle between draft and active document is only available for edit drafts and active documents with draft)
|
|
820
|
+
if (
|
|
821
|
+
!bIsDraft ||
|
|
822
|
+
!(
|
|
823
|
+
(!oContextData.IsActiveEntity && oContextData.HasActiveEntity) ||
|
|
824
|
+
(oContextData.IsActiveEntity && oContextData.HasDraftEntity)
|
|
825
|
+
)
|
|
826
|
+
) {
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
if (!oContextData.IsActiveEntity && oContextData.HasActiveEntity) {
|
|
831
|
+
//start Point: edit draft
|
|
832
|
+
bEditable = false;
|
|
833
|
+
} else if (oContextData.IsActiveEntity && oContextData.HasDraftEntity) {
|
|
834
|
+
// start point active document
|
|
835
|
+
bEditable = true;
|
|
836
|
+
}
|
|
837
|
+
oToggleContext
|
|
838
|
+
.requestCanonicalPath()
|
|
839
|
+
.then(function(sCanonicalPath: any) {
|
|
840
|
+
// We use the canonical path for the navigation instead of the semantic path, as the
|
|
841
|
+
// semantic key values may have changed between the draft and the active version (BCP 2170216142)
|
|
842
|
+
return oToggleContext
|
|
843
|
+
.getModel()
|
|
844
|
+
.bindContext(sCanonicalPath)
|
|
845
|
+
.getBoundContext();
|
|
846
|
+
})
|
|
847
|
+
.then((oToggleContext: any) => {
|
|
848
|
+
this._setEditMode(bEditable ? EditMode.Editable : EditMode.Display, false); //switch to edit mode only if a draft is available
|
|
849
|
+
this._handleNewContext(oToggleContext, bEditable, true, true, true);
|
|
850
|
+
})
|
|
851
|
+
.catch(function(err: any) {
|
|
852
|
+
return Promise.reject("Error in EditFlow.toggleDraftActive:" + err);
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
// Internal only params ---
|
|
857
|
+
// @param {sap.m.Button} mParameters.cancelButton - Currently this is passed as cancelButton internally (replaced by mParameters.control in the JSDoc below). Currently it is also mandatory.
|
|
858
|
+
// Plan - This should not be mandatory. If not provided, we should have a default that can act as reference control for the discard popover OR we can show a dialog instead of a popover.
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Discard the editable document.
|
|
862
|
+
*
|
|
863
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
864
|
+
* @param {object} oContext Context of the editable document
|
|
865
|
+
* @param {map} mParameters Can contain the following attributes:
|
|
866
|
+
* @param {object} mParameters.control This is the control used to open the discard popover
|
|
867
|
+
* @param {boolean} mParameters.skipDiscardPopover Optional, supresses the discard popover and allows custom handling
|
|
868
|
+
* @returns {Promise} Promise resolves once editable document has been discarded
|
|
869
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#cancelDocument
|
|
870
|
+
* @public
|
|
871
|
+
* @since 1.90.0
|
|
872
|
+
*/
|
|
873
|
+
@Public
|
|
874
|
+
@Final
|
|
875
|
+
cancelDocument(oContext: object, mParameters: { control: object; skipDiscardPopover?: boolean }): Promise<void> {
|
|
876
|
+
const transactionHelper = this._getTransactionHelper(),
|
|
877
|
+
oResourceBundle = (this.getView().getController() as any).oResourceBundle;
|
|
878
|
+
const mInParameters: any = mParameters;
|
|
879
|
+
mInParameters.cancelButton = mParameters.control || mInParameters.cancelButton;
|
|
880
|
+
mInParameters.beforeCancelCallBack = this.base.editFlow.onBeforeDiscard;
|
|
881
|
+
return this._syncTask()
|
|
882
|
+
.then(
|
|
883
|
+
transactionHelper.cancelDocument.bind(transactionHelper, oContext, mParameters, oResourceBundle, this._getMessageHandler())
|
|
884
|
+
)
|
|
885
|
+
.then((oActiveDocumentContext: any) => {
|
|
886
|
+
const bDraftNavigation = true,
|
|
887
|
+
sProgrammingModel = this._getProgrammingModel(oContext);
|
|
888
|
+
|
|
889
|
+
this._removeContextsFromPages();
|
|
890
|
+
if (sProgrammingModel === ProgrammingModel.Sticky) {
|
|
891
|
+
this._getInternalModel().setProperty("/sessionOn", false);
|
|
892
|
+
this._handleStickyOff(/*oContext*/);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
send(this.getView(), Activity.Discard, oActiveDocumentContext);
|
|
896
|
+
|
|
897
|
+
this._setEditMode(EditMode.Display, false);
|
|
898
|
+
this._setDraftStatus(DraftStatus.Clear);
|
|
899
|
+
|
|
900
|
+
//in case of a new document, the value of hasActiveEntity is returned. navigate back.
|
|
901
|
+
if (!oActiveDocumentContext) {
|
|
902
|
+
EditState.setEditStateDirty();
|
|
903
|
+
return mInParameters.skipBackNavigation ? undefined : this._getRoutingListener().navigateBackFromContext(oContext);
|
|
904
|
+
} else if (sProgrammingModel === ProgrammingModel.Draft) {
|
|
905
|
+
// We need to load the semantic keys of the active context, as we need them
|
|
906
|
+
// for the navigation
|
|
907
|
+
return this._fetchSemanticKeyValues(oActiveDocumentContext).then(() => {
|
|
908
|
+
// We force the recreation of the context, so that it's created and bound in the same microtask,
|
|
909
|
+
// so that all properties are loaded together by autoExpandSelect, so that when switching back to Edit mode
|
|
910
|
+
// $$inheritExpandSelect takes all loaded properties into account (BCP 2070462265)
|
|
911
|
+
if (mInParameters.skipBindingToView) {
|
|
912
|
+
return oActiveDocumentContext;
|
|
913
|
+
} else {
|
|
914
|
+
return this._handleNewContext(oActiveDocumentContext, false, true, bDraftNavigation, true);
|
|
915
|
+
}
|
|
916
|
+
});
|
|
917
|
+
} else {
|
|
918
|
+
//active context is returned in case of cancel of existing document
|
|
919
|
+
return this._handleNewContext(oActiveDocumentContext, false, false, bDraftNavigation, true);
|
|
920
|
+
}
|
|
921
|
+
})
|
|
922
|
+
.catch(function(oError: any) {
|
|
923
|
+
Log.error("Error while discarding the document", oError);
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// Internal only params ---
|
|
928
|
+
// @param {string} mParameters.entitySetName Name of the EntitySet to which the object belongs
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Deletes the document.
|
|
932
|
+
*
|
|
933
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
934
|
+
* @param {object} oContext Context of the document
|
|
935
|
+
* @param {object} mInParameters Can contain the following attributes:
|
|
936
|
+
* @param {string} mInParameters.title Title of the object being deleted
|
|
937
|
+
* @param {string} mInParameters.description Description of the object being deleted
|
|
938
|
+
* @returns {Promise} Promise resolves once document has been deleted
|
|
939
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#deleteDocument
|
|
940
|
+
* @public
|
|
941
|
+
* @since 1.90.0
|
|
942
|
+
*/
|
|
943
|
+
@Public
|
|
944
|
+
@Final
|
|
945
|
+
deleteDocument(oContext: Context, mInParameters: { title: string; description: string }): Promise<void> {
|
|
946
|
+
const oAppComponent = CommonUtils.getAppComponent(this.getView());
|
|
947
|
+
const sPath = oContext.getPath();
|
|
948
|
+
let mParameters: any = mInParameters;
|
|
949
|
+
if (!mParameters) {
|
|
950
|
+
mParameters = {
|
|
951
|
+
bFindActiveContexts: false
|
|
952
|
+
};
|
|
953
|
+
} else {
|
|
954
|
+
mParameters.bFindActiveContexts = false;
|
|
955
|
+
}
|
|
956
|
+
mParameters.beforeDeleteCallBack = this.base.editFlow.onBeforeDelete;
|
|
957
|
+
return this._deleteDocumentTransaction(oContext, mParameters)
|
|
958
|
+
.then(() => {
|
|
959
|
+
// Single objet deletion is triggered from an OP header button (not from a list)
|
|
960
|
+
// --> Mark UI dirty and navigate back to dismiss the OP
|
|
961
|
+
EditState.setEditStateDirty();
|
|
962
|
+
|
|
963
|
+
send(this.getView(), Activity.Delete, sPath);
|
|
964
|
+
|
|
965
|
+
this._getRoutingListener().navigateBackFromContext(oContext);
|
|
966
|
+
// After delete is successfull, we need to dettch the setBackNavigation Methods
|
|
967
|
+
if (oAppComponent) {
|
|
968
|
+
oAppComponent.getShellServices().setBackNavigation();
|
|
969
|
+
}
|
|
970
|
+
})
|
|
971
|
+
.catch(function(oError: any) {
|
|
972
|
+
Log.error("Error while deleting the document", oError);
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/**
|
|
977
|
+
* Submit the current set of changes and navigate back.
|
|
978
|
+
*
|
|
979
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
980
|
+
* @param {object} oContext Context of the document
|
|
981
|
+
* @returns {Promise} Promise resolves once the changes have been saved
|
|
982
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#applyDocument
|
|
983
|
+
* @public
|
|
984
|
+
* @since 1.90.0
|
|
985
|
+
*/
|
|
986
|
+
@Public
|
|
987
|
+
@Final
|
|
988
|
+
applyDocument(oContext: object): Promise<void> {
|
|
989
|
+
const oLockObject = this._getGlobalUIModel();
|
|
990
|
+
BusyLocker.lock(oLockObject);
|
|
991
|
+
return (
|
|
992
|
+
this._submitOpenChanges(oContext)
|
|
993
|
+
// check if there are any validation/parse errors
|
|
994
|
+
.then(this._checkForValidationErrors.bind(this, oContext))
|
|
995
|
+
.then(() => {
|
|
996
|
+
this._getMessageHandler().showMessageDialog();
|
|
997
|
+
this._getRoutingListener().navigateBackFromContext(oContext);
|
|
998
|
+
return true;
|
|
999
|
+
})
|
|
1000
|
+
.finally(function() {
|
|
1001
|
+
if (BusyLocker.isLocked(oLockObject)) {
|
|
1002
|
+
BusyLocker.unlock(oLockObject);
|
|
1003
|
+
}
|
|
1004
|
+
})
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
// Internal only params ---
|
|
1009
|
+
// @param {boolean} [mParameters.bStaticAction] Boolean value for static action, undefined for other actions
|
|
1010
|
+
// @param {boolean} [mParameters.isNavigable] Boolean value indicating whether navigation is required after the action has been executed
|
|
1011
|
+
// Currently the parameter isNavigable is used internally and should be changed to requiresNavigation as it is a more apt name for this param
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* Invokes an action (bound or unbound) and tracks the changes so that other pages can be refreshed and show the updated data upon navigation.
|
|
1015
|
+
*
|
|
1016
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
1017
|
+
* @param {string} sActionName The name of the action to be called
|
|
1018
|
+
* @param {object} mInParameters Contains the following attributes:
|
|
1019
|
+
* @param {sap.ui.model.odata.v4.Context} mInParameters.contexts For a bound action, a context or an array with contexts for which the action is to be called must be provided
|
|
1020
|
+
* @param {sap.ui.model.odata.v4.ODataModel} mInParameters.model For an unbound action, an instance of an OData V4 model must be provided
|
|
1021
|
+
* @param {boolean} mInParameters.requiresNavigation Boolean value indicating whether navigation is required after the action has been executed. Navigation takes place to the context returned by the action
|
|
1022
|
+
* @param {string} mInParameters.label A human-readable label for the action. This is needed in case the action has a parameter and a parameter dialog is shown to the user. The label will be used for the title of the dialog and for the confirmation button
|
|
1023
|
+
* @param {string} mInParameters.invocationGrouping Mode how actions are to be called: 'ChangeSet' to put all action calls into one changeset, 'Isolated' to put them into separate changesets
|
|
1024
|
+
* @param {object} mExtraParams PRIVATE
|
|
1025
|
+
* @returns {Promise}
|
|
1026
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#invokeAction
|
|
1027
|
+
* @public
|
|
1028
|
+
* @since 1.90.0
|
|
1029
|
+
* @final
|
|
1030
|
+
**/
|
|
1031
|
+
@Public
|
|
1032
|
+
@Final
|
|
1033
|
+
invokeAction(
|
|
1034
|
+
sActionName: string,
|
|
1035
|
+
mInParameters?: {
|
|
1036
|
+
contexts?: Context | Context[];
|
|
1037
|
+
model?: ODataModel;
|
|
1038
|
+
requiresNavigation?: boolean;
|
|
1039
|
+
label?: string;
|
|
1040
|
+
invocationGrouping?: string;
|
|
1041
|
+
},
|
|
1042
|
+
mExtraParams?: any
|
|
1043
|
+
): Promise<void> {
|
|
1044
|
+
let oControl: any;
|
|
1045
|
+
const transactionHelper = this._getTransactionHelper();
|
|
1046
|
+
let oCurrentControl;
|
|
1047
|
+
let oBindingContext;
|
|
1048
|
+
let aParts;
|
|
1049
|
+
let sOverloadEntityType;
|
|
1050
|
+
let oCurrentActionCallBacks: any;
|
|
1051
|
+
const oView = this.getView();
|
|
1052
|
+
|
|
1053
|
+
let mParameters: any = mInParameters || {};
|
|
1054
|
+
|
|
1055
|
+
// Due to a mistake the invokeAction in the extensionAPI had a different API than this one.
|
|
1056
|
+
// The one from the extensionAPI doesn't exist anymore as we expose the full edit flow now but
|
|
1057
|
+
// due to compatibility reasons we still need to support the old signature
|
|
1058
|
+
if ((mParameters.isA && mParameters.isA("sap.ui.model.odata.v4.Context")) || Array.isArray(mParameters) || arguments.length === 3) {
|
|
1059
|
+
const contexts = mParameters;
|
|
1060
|
+
mParameters = mExtraParams || {};
|
|
1061
|
+
if (contexts) {
|
|
1062
|
+
mParameters.contexts = contexts;
|
|
1063
|
+
} else {
|
|
1064
|
+
mParameters.model = this.getView().getModel();
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
mParameters.isNavigable = mParameters.requiresNavigation || mParameters.isNavigable;
|
|
1069
|
+
|
|
1070
|
+
if (!mParameters.parentControl) {
|
|
1071
|
+
mParameters.parentControl = this.getView();
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
if (mParameters.controlId) {
|
|
1075
|
+
oControl = this.getView().byId(mParameters.controlId);
|
|
1076
|
+
if (oControl) {
|
|
1077
|
+
// TODO: currently this selected contexts update is done within the operation, should be moved out
|
|
1078
|
+
mParameters.internalModelContext = oControl.getBindingContext("internal");
|
|
1079
|
+
}
|
|
1080
|
+
} else {
|
|
1081
|
+
mParameters.internalModelContext = oView.getBindingContext("internal");
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
if (sActionName && sActionName.indexOf("(") > -1) {
|
|
1085
|
+
// get entity type of action overload and remove it from the action path
|
|
1086
|
+
// Example sActionName = "<ActionName>(Collection(<OverloadEntityType>))"
|
|
1087
|
+
// sActionName = aParts[0] --> <ActionName>
|
|
1088
|
+
// sOverloadEntityType = aParts[2] --> <OverloadEntityType>
|
|
1089
|
+
aParts = sActionName.split("(");
|
|
1090
|
+
sActionName = aParts[0];
|
|
1091
|
+
sOverloadEntityType = (aParts[aParts.length - 1] as any).replaceAll(")", "");
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
if (mParameters.bStaticAction) {
|
|
1095
|
+
if (oControl.isTableBound()) {
|
|
1096
|
+
mParameters.contexts = oControl.getRowBinding().getHeaderContext();
|
|
1097
|
+
} else {
|
|
1098
|
+
const sBindingPath = oControl.data("rowsBindingInfo").path,
|
|
1099
|
+
oListBinding = new (ODataListBinding as any)(this.getView().getModel(), sBindingPath);
|
|
1100
|
+
mParameters.contexts = oListBinding.getHeaderContext();
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
if (sOverloadEntityType) {
|
|
1104
|
+
const sTableContextEntityType = mParameters.contexts
|
|
1105
|
+
.getModel()
|
|
1106
|
+
.getMetaModel()
|
|
1107
|
+
.getMetaContext(mParameters.contexts.getPath())
|
|
1108
|
+
.getObject("$Type");
|
|
1109
|
+
if (sOverloadEntityType !== sTableContextEntityType) {
|
|
1110
|
+
// search for context in control tree hierarchy
|
|
1111
|
+
oCurrentControl = oControl;
|
|
1112
|
+
while (oCurrentControl) {
|
|
1113
|
+
oBindingContext = oCurrentControl.getBindingContext();
|
|
1114
|
+
if (
|
|
1115
|
+
oBindingContext &&
|
|
1116
|
+
oBindingContext
|
|
1117
|
+
.getModel()
|
|
1118
|
+
.getMetaModel()
|
|
1119
|
+
.getMetaContext(oBindingContext.getPath())
|
|
1120
|
+
.getObject("$Type") === sOverloadEntityType
|
|
1121
|
+
) {
|
|
1122
|
+
mParameters.contexts = oBindingContext;
|
|
1123
|
+
break;
|
|
1124
|
+
} else {
|
|
1125
|
+
// check parent
|
|
1126
|
+
oCurrentControl = oCurrentControl.getParent();
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
// context was not found in UI hierarchy going straight upwards - try to find it in SubSections
|
|
1130
|
+
if (!oCurrentControl) {
|
|
1131
|
+
const oActionOverloadContext = this._getActionOverloadContextFromSubSections(oControl, sOverloadEntityType);
|
|
1132
|
+
if (oActionOverloadContext !== undefined) {
|
|
1133
|
+
mParameters.contexts = oActionOverloadContext;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
if (!mParameters.contexts) {
|
|
1138
|
+
return Promise.reject("Context not found for entity type " + sOverloadEntityType);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
if (mParameters.enableAutoScroll) {
|
|
1144
|
+
oCurrentActionCallBacks = this._createActionPromise(sActionName, oControl.sId);
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
if (mParameters.isNavigable) {
|
|
1149
|
+
mParameters.bGetBoundContext = false;
|
|
1150
|
+
} else {
|
|
1151
|
+
mParameters.bGetBoundContext = true;
|
|
1152
|
+
}
|
|
1153
|
+
// Need to know that the action is called from ObjectPage for changeSet Isolated workaround
|
|
1154
|
+
mParameters.bObjectPage = (oView.getViewData() as any).converterType === "ObjectPage";
|
|
1155
|
+
return this._syncTask()
|
|
1156
|
+
.then(transactionHelper.callAction.bind(transactionHelper, sActionName, mParameters, this.getView(), this._getMessageHandler()))
|
|
1157
|
+
.then((oResponse: any) => {
|
|
1158
|
+
// if the returned context for the bound action is different than the context on which action was called,
|
|
1159
|
+
// refresh the corresponding list binding
|
|
1160
|
+
if (mParameters.contexts) {
|
|
1161
|
+
return this._refreshListIfRequired(
|
|
1162
|
+
this._getActionResponseDataAndKeys(sActionName, oResponse),
|
|
1163
|
+
mParameters.contexts[0]
|
|
1164
|
+
).then(function() {
|
|
1165
|
+
return oResponse;
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
})
|
|
1169
|
+
.then((oResponse: any) => {
|
|
1170
|
+
send(this.getView(), Activity.Action, mParameters.contexts);
|
|
1171
|
+
|
|
1172
|
+
if (oCurrentActionCallBacks) {
|
|
1173
|
+
oCurrentActionCallBacks.fResolver(oResponse);
|
|
1174
|
+
}
|
|
1175
|
+
/*
|
|
1176
|
+
We set the (upper) pages to dirty after an execution of an action
|
|
1177
|
+
TODO: get rid of this workaround
|
|
1178
|
+
This workaround is only needed as long as the model does not support the synchronization.
|
|
1179
|
+
Once this is supported we don't need to set the pages to dirty anymore as the context itself
|
|
1180
|
+
is already refreshed (it's just not reflected in the object page)
|
|
1181
|
+
we explicitly don't call this method from the list report but only call it from the object page
|
|
1182
|
+
as if it is called in the list report it's not needed - as we anyway will remove this logic
|
|
1183
|
+
we can live with this
|
|
1184
|
+
we need a context to set the upper pages to dirty - if there are more than one we use the
|
|
1185
|
+
first one as they are anyway siblings
|
|
1186
|
+
*/
|
|
1187
|
+
if (mParameters.contexts) {
|
|
1188
|
+
EditState.setEditStateDirty();
|
|
1189
|
+
this._getInternalModel().setProperty("/sCustomAction", sActionName);
|
|
1190
|
+
}
|
|
1191
|
+
if (mParameters.isNavigable) {
|
|
1192
|
+
let vContext = oResponse;
|
|
1193
|
+
if (Array.isArray(vContext) && vContext.length === 1) {
|
|
1194
|
+
vContext = vContext[0];
|
|
1195
|
+
}
|
|
1196
|
+
if (vContext && !Array.isArray(vContext)) {
|
|
1197
|
+
const oMetaModel = oView.getModel().getMetaModel() as ODataMetaModel;
|
|
1198
|
+
const sContextMetaPath = oMetaModel.getMetaPath(vContext.getPath());
|
|
1199
|
+
const oActionContext = Array.isArray(mParameters.contexts) ? mParameters.contexts[0] : mParameters.contexts;
|
|
1200
|
+
const sActionContextMetaPath = oActionContext && oMetaModel.getMetaPath(oActionContext.getPath());
|
|
1201
|
+
if (sContextMetaPath != undefined && sContextMetaPath === sActionContextMetaPath) {
|
|
1202
|
+
if (oActionContext.getPath() !== vContext.getPath()) {
|
|
1203
|
+
this._getRoutingListener().navigateForwardToContext(vContext, {
|
|
1204
|
+
noHistoryEntry: false
|
|
1205
|
+
});
|
|
1206
|
+
} else {
|
|
1207
|
+
Log.info("Navigation to the same context is not allowed");
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
})
|
|
1213
|
+
.catch(function(err: any) {
|
|
1214
|
+
if (oCurrentActionCallBacks) {
|
|
1215
|
+
oCurrentActionCallBacks.fRejector();
|
|
1216
|
+
}
|
|
1217
|
+
if (err == Constants.CancelActionDialog) {
|
|
1218
|
+
return Promise.reject("Dialog cancelled.");
|
|
1219
|
+
} else {
|
|
1220
|
+
return Promise.reject("Error in EditFlow.invokeAction:" + err);
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* Secured execution of the given function. Ensures that the function is only executed when certain conditions are fulfilled.
|
|
1227
|
+
*
|
|
1228
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
1229
|
+
* @param {Function} fnFunction The function to be executed. Should return a promise that is settled after completion of the execution. If nothing is returned, immediate completion is assumed.
|
|
1230
|
+
* @param {object} mParameters Definitions of the preconditions to be checked before execution
|
|
1231
|
+
* @param {object} mParameters.busy Defines the busy indicator
|
|
1232
|
+
* @param {boolean} mParameters.busy.set Triggers a busy indicator when the function is executed.
|
|
1233
|
+
* @param {boolean} mParameters.busy.check Executes function only if application isn't busy.
|
|
1234
|
+
* @param {boolean} mParameters.updatesDocument This operation updates the current document without using the bound model and context. As a result, the draft status is updated if a draft document exists, and the user has to confirm the cancellation of the editing process.
|
|
1235
|
+
* @returns {Promise} A promise that is rejected if the execution is prohibited and resolved by the promise returned by the fnFunction.
|
|
1236
|
+
* @alias sap.fe.core.controllerextensions.EditFlow#securedExecution
|
|
1237
|
+
* @public
|
|
1238
|
+
* @experimental As of version 1.90.0
|
|
1239
|
+
* @since 1.90.0
|
|
1240
|
+
*/
|
|
1241
|
+
@Public
|
|
1242
|
+
@Final
|
|
1243
|
+
securedExecution(
|
|
1244
|
+
fnFunction: Function,
|
|
1245
|
+
mParameters?: {
|
|
1246
|
+
busy?: {
|
|
1247
|
+
set?: boolean;
|
|
1248
|
+
check?: boolean;
|
|
1249
|
+
};
|
|
1250
|
+
updatesDocument?: boolean;
|
|
1251
|
+
}
|
|
1252
|
+
): Promise<void> {
|
|
1253
|
+
const bBusySet = mParameters && mParameters.busy && mParameters.busy.set !== undefined ? mParameters.busy.set : true,
|
|
1254
|
+
bBusyCheck = mParameters && mParameters.busy && mParameters.busy.check !== undefined ? mParameters.busy.check : true,
|
|
1255
|
+
bUpdatesDocument = (mParameters && (mParameters as any).updatesDocument) || false,
|
|
1256
|
+
oLockObject = this._getGlobalUIModel(),
|
|
1257
|
+
oContext = this.base.getView().getBindingContext(),
|
|
1258
|
+
bIsDraft = oContext && this._getProgrammingModel(oContext) === ProgrammingModel.Draft;
|
|
1259
|
+
|
|
1260
|
+
if (bBusyCheck && BusyLocker.isLocked(oLockObject)) {
|
|
1261
|
+
return Promise.reject("Application already busy therefore execution rejected");
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
// we have to set busy and draft indicator immediately also the function might be executed later in queue
|
|
1265
|
+
if (bBusySet) {
|
|
1266
|
+
BusyLocker.lock(oLockObject);
|
|
1267
|
+
}
|
|
1268
|
+
if (bUpdatesDocument && bIsDraft) {
|
|
1269
|
+
this._setDraftStatus(DraftStatus.Saving);
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
this._getMessageHandler().removeTransitionMessages();
|
|
1273
|
+
|
|
1274
|
+
return this._syncTask(fnFunction)
|
|
1275
|
+
.then(() => {
|
|
1276
|
+
if (bUpdatesDocument) {
|
|
1277
|
+
this._getTransactionHelper().handleDocumentModifications();
|
|
1278
|
+
EditState.setEditStateDirty();
|
|
1279
|
+
if (bIsDraft) {
|
|
1280
|
+
this._setDraftStatus(DraftStatus.Saved);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
})
|
|
1284
|
+
.catch((oError: any) => {
|
|
1285
|
+
if (bUpdatesDocument && bIsDraft) {
|
|
1286
|
+
this._setDraftStatus(DraftStatus.Clear);
|
|
1287
|
+
}
|
|
1288
|
+
return Promise.reject(oError);
|
|
1289
|
+
})
|
|
1290
|
+
.finally(() => {
|
|
1291
|
+
if (bBusySet) {
|
|
1292
|
+
BusyLocker.unlock(oLockObject);
|
|
1293
|
+
}
|
|
1294
|
+
return this._getMessageHandler().showMessageDialog();
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
/**
|
|
1299
|
+
* Handles the patchSent event: register document modification.
|
|
1300
|
+
*
|
|
1301
|
+
* @param oEvent
|
|
1302
|
+
*/
|
|
1303
|
+
@Public
|
|
1304
|
+
handlePatchSent(oEvent: any) {
|
|
1305
|
+
this.mPatchPromises = this.mPatchPromises ? this.mPatchPromises : {};
|
|
1306
|
+
// do this for every unique object (eg: every table) so that each associated promise is fulfilled at the end
|
|
1307
|
+
const oPatchPromise = new Promise((resolve, reject) => {
|
|
1308
|
+
this.mPatchPromises[oEvent.getSource()] = {
|
|
1309
|
+
resolvePatchPromise: resolve,
|
|
1310
|
+
rejectPatchPromise: reject
|
|
1311
|
+
};
|
|
1312
|
+
});
|
|
1313
|
+
this.updateDocument(oEvent.getSource(), oPatchPromise);
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
/**
|
|
1317
|
+
* Handles the patchCompleted event: resolves or rejects document modification.
|
|
1318
|
+
*
|
|
1319
|
+
* @param oEvent
|
|
1320
|
+
*/
|
|
1321
|
+
@Public
|
|
1322
|
+
handlePatchCompleted(oEvent: any) {
|
|
1323
|
+
const bSuccess = oEvent.getParameter("success");
|
|
1324
|
+
if (bSuccess) {
|
|
1325
|
+
this.mPatchPromises[oEvent.getSource()].resolvePatchPromise();
|
|
1326
|
+
} else {
|
|
1327
|
+
this.mPatchPromises[oEvent.getSource()].rejectPatchPromise();
|
|
1328
|
+
}
|
|
1329
|
+
delete this.mPatchPromises[oEvent.getSource()];
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
//////////////////////////////////////
|
|
1333
|
+
// Private methods
|
|
1334
|
+
//////////////////////////////////////
|
|
1335
|
+
|
|
1336
|
+
/*
|
|
1337
|
+
TO BE CHECKED / DISCUSSED
|
|
1338
|
+
_createMultipleDocuments and deleteMultiDocument - couldn't we combine them with create and delete document?
|
|
1339
|
+
_createActionPromise and deleteCurrentActionPromise -> next step
|
|
1340
|
+
|
|
1341
|
+
*/
|
|
1342
|
+
|
|
1343
|
+
_setEditMode(sEditMode: any, bCreationMode?: boolean) {
|
|
1344
|
+
(this.base.getView().getController() as PageController)._editFlow.setEditMode(sEditMode, bCreationMode);
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
_setDraftStatus(sDraftState: any) {
|
|
1348
|
+
(this.base.getView().getController() as PageController)._editFlow.setDraftStatus(sDraftState);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
_getRoutingListener() {
|
|
1352
|
+
return (this.base.getView().getController() as PageController)._editFlow.getRoutingListener();
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
_getGlobalUIModel() {
|
|
1356
|
+
return (this.base.getView().getController() as PageController)._editFlow.getGlobalUIModel();
|
|
1357
|
+
}
|
|
1358
|
+
_syncTask(vTask?: any) {
|
|
1359
|
+
return (this.base.getView().getController() as PageController)._editFlow.syncTask(vTask);
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
_getProgrammingModel(oContext: any) {
|
|
1363
|
+
return (this.base.getView().getController() as PageController)._editFlow.getProgrammingModel(oContext);
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
_deleteDocumentTransaction(oContext: any, mParameters: any) {
|
|
1367
|
+
return (this.base.getView().getController() as PageController)._editFlow.deleteDocumentTransaction(oContext, mParameters);
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
_handleCreateEvents(oBinding: any) {
|
|
1371
|
+
(this.base.getView().getController() as PageController)._editFlow.handleCreateEvents(oBinding);
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
_getTransactionHelper() {
|
|
1375
|
+
return (this.base.getView().getController() as PageController)._editFlow.getTransactionHelper();
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
_getInternalModel() {
|
|
1379
|
+
return (this.base.getView().getController() as PageController)._editFlow.getInternalModel();
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
/**
|
|
1383
|
+
* Creates a new promise to wait for an action to be executed
|
|
1384
|
+
*
|
|
1385
|
+
* @function
|
|
1386
|
+
* @name _createActionPromise
|
|
1387
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
1388
|
+
*
|
|
1389
|
+
* @returns {Function} The resolver function which can be used to externally resolve the promise
|
|
1390
|
+
*/
|
|
1391
|
+
|
|
1392
|
+
_createActionPromise(sActionName: any, sControlId: any) {
|
|
1393
|
+
return (this.base.getView().getController() as PageController)._editFlow.createActionPromise(sActionName, sControlId);
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
_getCurrentActionPromise() {
|
|
1397
|
+
return (this.base.getView().getController() as PageController)._editFlow.getCurrentActionPromise();
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
_deleteCurrentActionPromise() {
|
|
1401
|
+
return (this.base.getView().getController() as PageController)._editFlow.deleteCurrentActionPromise();
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
_getMessageHandler() {
|
|
1405
|
+
return (this.base.getView().getController() as PageController)._editFlow.getMessageHandler();
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
/**
|
|
1409
|
+
* @function
|
|
1410
|
+
* @name _getActionResponseDataAndKeys
|
|
1411
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
1412
|
+
* @param {string} sActionName The name of the action that is executed
|
|
1413
|
+
* @param {object} oResponse The bound action's response data or response context
|
|
1414
|
+
* @returns {object} Object with data and names of the key fields of the response
|
|
1415
|
+
*/
|
|
1416
|
+
_getActionResponseDataAndKeys(sActionName: string, oResponse: object) {
|
|
1417
|
+
return (this.base.getView().getController() as PageController)._editFlow.getActionResponseDataAndKeys(sActionName, oResponse);
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
_submitOpenChanges(oContext: any) {
|
|
1421
|
+
const oModel = oContext.getModel(),
|
|
1422
|
+
oLockObject = this._getGlobalUIModel();
|
|
1423
|
+
//Currently we are using only 1 updateGroupId, hence submitting the batch directly here
|
|
1424
|
+
return oModel
|
|
1425
|
+
.submitBatch("$auto")
|
|
1426
|
+
.then(function() {
|
|
1427
|
+
if (oModel.hasPendingChanges("$auto")) {
|
|
1428
|
+
// the submit was not successful
|
|
1429
|
+
return Promise.reject("submit of open changes failed");
|
|
1430
|
+
}
|
|
1431
|
+
})
|
|
1432
|
+
.finally(function() {
|
|
1433
|
+
if (BusyLocker.isLocked(oLockObject)) {
|
|
1434
|
+
BusyLocker.unlock(oLockObject);
|
|
1435
|
+
}
|
|
1436
|
+
});
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
_handleStickyOn(oContext: Context) {
|
|
1440
|
+
return (this.base.getView().getController() as PageController)._editFlow.handleStickyOn(oContext);
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
_handleStickyOff() {
|
|
1444
|
+
return (this.base.getView().getController() as PageController)._editFlow.handleStickyOff();
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
_onBackNavigationInSession() {
|
|
1448
|
+
return (this.base.getView().getController() as PageController)._editFlow.onBackNavigationInSession();
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
_discardStickySession(oContext: Context) {
|
|
1452
|
+
return (this.base.getView().getController() as PageController)._editFlow.discardStickySession(oContext);
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
_handleNewContext(oContext: any, bEditable: boolean, bRecreateContext: boolean, bDraftNavigation: boolean, bForceFocus?: boolean) {
|
|
1456
|
+
EditState.setEditStateDirty();
|
|
1457
|
+
|
|
1458
|
+
return this._getRoutingListener().navigateToContext(oContext, {
|
|
1459
|
+
checkNoHashChange: true,
|
|
1460
|
+
editable: bEditable,
|
|
1461
|
+
bPersistOPScroll: true,
|
|
1462
|
+
bRecreateContext: bRecreateContext,
|
|
1463
|
+
bDraftNavigation: bDraftNavigation,
|
|
1464
|
+
showPlaceholder: false,
|
|
1465
|
+
bForceFocus: bForceFocus
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
/**
|
|
1470
|
+
* Checks if there are validation (parse) errors for controls bound to a given context
|
|
1471
|
+
*
|
|
1472
|
+
* @function
|
|
1473
|
+
* @name _checkForValidationErrors
|
|
1474
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
1475
|
+
* @returns {Promise} Promise resolves if there are no validation errors, and rejects if there are validation errors
|
|
1476
|
+
*/
|
|
1477
|
+
|
|
1478
|
+
_checkForValidationErrors() {
|
|
1479
|
+
return this._syncTask().then(() => {
|
|
1480
|
+
const sViewId = this.base.getView().getId();
|
|
1481
|
+
const aMessages = sap.ui
|
|
1482
|
+
.getCore()
|
|
1483
|
+
.getMessageManager()
|
|
1484
|
+
.getMessageModel()
|
|
1485
|
+
.getData();
|
|
1486
|
+
let oControl;
|
|
1487
|
+
let oMessage;
|
|
1488
|
+
|
|
1489
|
+
if (!aMessages.length) {
|
|
1490
|
+
return Promise.resolve("No validation errors found");
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
for (let i = 0; i < aMessages.length; i++) {
|
|
1494
|
+
oMessage = aMessages[i];
|
|
1495
|
+
if (oMessage.validation) {
|
|
1496
|
+
oControl = sap.ui.getCore().byId(oMessage.getControlId());
|
|
1497
|
+
while (oControl) {
|
|
1498
|
+
if (oControl.getId() === sViewId) {
|
|
1499
|
+
return Promise.reject("validation errors exist");
|
|
1500
|
+
}
|
|
1501
|
+
oControl = oControl.getParent();
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
/**
|
|
1509
|
+
* @function
|
|
1510
|
+
* @name _refreshListIfRequired
|
|
1511
|
+
* @memberof sap.fe.core.controllerextensions.EditFlow
|
|
1512
|
+
* @param {object} oResponse The response of the bound action and the names of the key fields
|
|
1513
|
+
* @param {sap.ui.model.odata.v4.Context} oContext The bound context on which the action was executed
|
|
1514
|
+
* @returns {Promise} Always resolves to param oResponse
|
|
1515
|
+
*/
|
|
1516
|
+
_refreshListIfRequired(oResponse: any, oContext: Context) {
|
|
1517
|
+
if (!oContext || !oResponse || !oResponse.oData) {
|
|
1518
|
+
return Promise.resolve();
|
|
1519
|
+
}
|
|
1520
|
+
const oBinding = oContext.getBinding();
|
|
1521
|
+
// refresh only lists
|
|
1522
|
+
if (oBinding && oBinding.isA("sap.ui.model.odata.v4.ODataListBinding")) {
|
|
1523
|
+
const oContextData = oResponse.oData;
|
|
1524
|
+
const aKeys = oResponse.keys;
|
|
1525
|
+
const oCurrentData = oContext.getObject();
|
|
1526
|
+
let bReturnedContextIsSame = true;
|
|
1527
|
+
// ensure context is in the response
|
|
1528
|
+
if (Object.keys(oContextData).length) {
|
|
1529
|
+
// check if context in response is different than the bound context
|
|
1530
|
+
bReturnedContextIsSame = aKeys.every(function(sKey: any) {
|
|
1531
|
+
return oCurrentData[sKey] === oContextData[sKey];
|
|
1532
|
+
});
|
|
1533
|
+
if (!bReturnedContextIsSame) {
|
|
1534
|
+
return new Promise<void>(resolve => {
|
|
1535
|
+
if ((oBinding as any).isRoot()) {
|
|
1536
|
+
oBinding.attachEventOnce("dataReceived", function() {
|
|
1537
|
+
resolve();
|
|
1538
|
+
});
|
|
1539
|
+
oBinding.refresh();
|
|
1540
|
+
} else {
|
|
1541
|
+
const oAppComponent = CommonUtils.getAppComponent(this.getView());
|
|
1542
|
+
oAppComponent
|
|
1543
|
+
.getSideEffectsService()
|
|
1544
|
+
.requestSideEffects([{ $NavigationPropertyPath: oBinding.getPath() }], oBinding.getContext() as Context)
|
|
1545
|
+
.then(
|
|
1546
|
+
function() {
|
|
1547
|
+
resolve();
|
|
1548
|
+
},
|
|
1549
|
+
function() {
|
|
1550
|
+
Log.error("Error while refreshing the table");
|
|
1551
|
+
resolve();
|
|
1552
|
+
}
|
|
1553
|
+
)
|
|
1554
|
+
.catch(function(e: any) {
|
|
1555
|
+
Log.error("Error while refreshing the table", e);
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
// resolve with oResponse to not disturb the promise chain afterwards
|
|
1563
|
+
return Promise.resolve();
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
_fetchSemanticKeyValues(oContext: any) {
|
|
1567
|
+
const oMetaModel = oContext.getModel().getMetaModel(),
|
|
1568
|
+
sEntitySetName = oMetaModel.getMetaContext(oContext.getPath()).getObject("@sapui.name"),
|
|
1569
|
+
aSemanticKeys = SemanticKeyHelper.getSemanticKeys(oMetaModel, sEntitySetName);
|
|
1570
|
+
|
|
1571
|
+
if (aSemanticKeys && aSemanticKeys.length) {
|
|
1572
|
+
const aRequestPromises = aSemanticKeys.map(function(oKey: any) {
|
|
1573
|
+
return oContext.requestObject(oKey.$PropertyPath);
|
|
1574
|
+
});
|
|
1575
|
+
|
|
1576
|
+
return Promise.all(aRequestPromises);
|
|
1577
|
+
} else {
|
|
1578
|
+
return Promise.resolve();
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
// Ugly Workaround to overcome mdc field issue, we remove the binding context before
|
|
1583
|
+
// switching to display mode to avoid the field reads additional values for non existing
|
|
1584
|
+
// drafts or sticky sessions in the backend
|
|
1585
|
+
_removeContextsFromPages() {
|
|
1586
|
+
let aPages: any[] = [];
|
|
1587
|
+
const oAppComponent = CommonUtils.getAppComponent(this.getView());
|
|
1588
|
+
|
|
1589
|
+
if (oAppComponent._isFclEnabled()) {
|
|
1590
|
+
const oFCL = oAppComponent.getRootContainer() as FlexibleColumnLayout;
|
|
1591
|
+
aPages = aPages.concat(oFCL.getMidColumnPages() || []);
|
|
1592
|
+
aPages = aPages.concat(oFCL.getEndColumnPages() || []);
|
|
1593
|
+
} else {
|
|
1594
|
+
const oNavContainer = oAppComponent.getRootContainer() as NavContainer;
|
|
1595
|
+
aPages = oNavContainer.getPages() || [];
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
aPages.forEach(function(oPage: any) {
|
|
1599
|
+
if (oPage.isA("sap.ui.core.ComponentContainer")) {
|
|
1600
|
+
oPage = oPage.getComponentInstance(); // The binding context is set at the component level, not the component container
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
if (oPage.getBindingContext()) {
|
|
1604
|
+
oPage.setBindingContext(null);
|
|
1605
|
+
}
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
_getActionOverloadContextFromSubSections(oControl: any, sOverloadEntityType: string) {
|
|
1610
|
+
let oCurrentControl: any;
|
|
1611
|
+
|
|
1612
|
+
function _checkActions(aActions: Array<object>) {
|
|
1613
|
+
let oActionBindingContext: any;
|
|
1614
|
+
try {
|
|
1615
|
+
aActions.forEach(function(oAction: any) {
|
|
1616
|
+
oActionBindingContext = oAction.getBindingContext();
|
|
1617
|
+
if (
|
|
1618
|
+
oActionBindingContext
|
|
1619
|
+
.getModel()
|
|
1620
|
+
.getMetaModel()
|
|
1621
|
+
.getMetaContext(oActionBindingContext.getPath())
|
|
1622
|
+
.getObject("$Type") === sOverloadEntityType
|
|
1623
|
+
) {
|
|
1624
|
+
throw "context found - stop actions loop";
|
|
1625
|
+
}
|
|
1626
|
+
});
|
|
1627
|
+
return undefined;
|
|
1628
|
+
} catch (e) {
|
|
1629
|
+
return oActionBindingContext;
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1633
|
+
function _checkSubSections(aSubSections: Array<object>) {
|
|
1634
|
+
let oActionBindingContext: any;
|
|
1635
|
+
try {
|
|
1636
|
+
aSubSections.forEach(function(oSubSection: any) {
|
|
1637
|
+
if (oActionBindingContext) {
|
|
1638
|
+
throw "context found - stop SubSections loop";
|
|
1639
|
+
}
|
|
1640
|
+
const aActions = oSubSection.getAggregation("actions");
|
|
1641
|
+
oActionBindingContext = _checkActions(aActions);
|
|
1642
|
+
});
|
|
1643
|
+
return oActionBindingContext ? oActionBindingContext : undefined;
|
|
1644
|
+
} catch (e) {
|
|
1645
|
+
return oActionBindingContext;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
try {
|
|
1650
|
+
if (oControl === undefined) {
|
|
1651
|
+
throw new Error("input parameter oControl undefined when trying to determine the action overload context");
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
oCurrentControl = oControl;
|
|
1655
|
+
while (!oCurrentControl.isA("sap.uxap.ObjectPageSection")) {
|
|
1656
|
+
oCurrentControl = oCurrentControl.getParent();
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
if (!oCurrentControl) {
|
|
1660
|
+
throw new Error("ObjectPageSection not found in UI hierarchy");
|
|
1661
|
+
} else {
|
|
1662
|
+
const aSubSections = oCurrentControl.getAggregation("subSections");
|
|
1663
|
+
return _checkSubSections(aSubSections);
|
|
1664
|
+
}
|
|
1665
|
+
} catch (error) {
|
|
1666
|
+
Log.info(error);
|
|
1667
|
+
return undefined;
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
export default EditFlow;
|