@sapui5/sap.fe.core 1.97.0 → 1.99.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -4
- package/src/sap/fe/core/.library +1 -1
- package/src/sap/fe/core/AnnotationHelper.js +377 -405
- package/src/sap/fe/core/AnnotationHelper.ts +385 -0
- package/src/sap/fe/core/AppComponent.js +6 -3
- package/src/sap/fe/core/AppStateHandler.js +229 -181
- package/src/sap/fe/core/AppStateHandler.ts +171 -0
- package/src/sap/fe/core/BaseController.js +3 -2
- 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 +2073 -2379
- package/src/sap/fe/core/CommonUtils.ts +2078 -0
- package/src/sap/fe/core/ExtensionAPI.js +16 -7
- package/src/sap/fe/core/PageController.js +84 -119
- package/src/sap/fe/core/PageController.ts +101 -0
- package/src/sap/fe/core/RouterProxy.js +986 -807
- package/src/sap/fe/core/RouterProxy.ts +838 -0
- package/src/sap/fe/core/Synchronization.js +51 -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 +166 -0
- package/src/sap/fe/core/TemplateModel.js +97 -54
- package/src/sap/fe/core/TemplateModel.ts +64 -0
- package/src/sap/fe/core/TransactionHelper.js +1576 -1579
- package/src/sap/fe/core/TransactionHelper.ts +1706 -0
- package/src/sap/fe/core/actions/draft.js +560 -581
- package/src/sap/fe/core/actions/draft.ts +594 -0
- package/src/sap/fe/core/actions/messageHandling.js +545 -511
- package/src/sap/fe/core/actions/messageHandling.ts +532 -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 +1074 -1211
- package/src/sap/fe/core/actions/operations.ts +1162 -0
- package/src/sap/fe/core/actions/sticky.js +102 -105
- package/src/sap/fe/core/actions/sticky.ts +102 -0
- package/src/sap/fe/core/controllerextensions/ControllerExtensionMetadata.js +3 -2
- package/src/sap/fe/core/controllerextensions/EditFlow.js +229 -260
- package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +3 -2
- package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +288 -13
- package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +27 -23
- package/src/sap/fe/core/controllerextensions/InternalRouting.js +82 -46
- package/src/sap/fe/core/controllerextensions/KPIManagement.js +113 -25
- package/src/sap/fe/core/controllerextensions/KPIManagement.ts +135 -44
- package/src/sap/fe/core/controllerextensions/MassEdit.js +172 -0
- package/src/sap/fe/core/controllerextensions/MessageHandler.js +22 -9
- package/src/sap/fe/core/controllerextensions/PageReady.js +3 -3
- package/src/sap/fe/core/controllerextensions/PageReady.ts +12 -8
- package/src/sap/fe/core/controllerextensions/Paginator.js +37 -9
- package/src/sap/fe/core/controllerextensions/Placeholder.js +8 -4
- package/src/sap/fe/core/controllerextensions/Routing.js +25 -5
- package/src/sap/fe/core/controllerextensions/RoutingListener.js +3 -2
- package/src/sap/fe/core/controllerextensions/Share.js +22 -8
- package/src/sap/fe/core/controllerextensions/SideEffects.js +9 -9
- package/src/sap/fe/core/controllerextensions/SideEffects.ts +22 -21
- package/src/sap/fe/core/controllerextensions/ViewState.js +3 -2
- package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +2 -1
- package/src/sap/fe/core/controls/CommandExecution.js +3 -2
- package/src/sap/fe/core/controls/ConditionalWrapper.js +3 -2
- package/src/sap/fe/core/controls/CustomQuickViewPage.js +3 -2
- package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +9 -5
- package/src/sap/fe/core/controls/FieldWrapper.js +18 -23
- package/src/sap/fe/core/controls/FilterBar.js +3 -2
- package/src/sap/fe/core/controls/FormElementWrapper.js +3 -7
- package/src/sap/fe/core/controls/MultiValueParameterDelegate.js +3 -2
- package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +2 -1
- package/src/sap/fe/core/controls/filterbar/FilterContainer.js +3 -2
- package/src/sap/fe/core/controls/filterbar/VisualFilter.js +5 -4
- package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +3 -2
- package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +3 -2
- 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/converters/ConverterContext.js +14 -2
- package/src/sap/fe/core/converters/ConverterContext.ts +14 -3
- package/src/sap/fe/core/converters/ManifestSettings.js +1 -1
- package/src/sap/fe/core/converters/ManifestSettings.ts +4 -0
- package/src/sap/fe/core/converters/ManifestWrapper.js +56 -32
- package/src/sap/fe/core/converters/ManifestWrapper.ts +24 -6
- package/src/sap/fe/core/converters/MetaModelConverter.js +67 -6
- package/src/sap/fe/core/converters/MetaModelConverter.ts +70 -14
- package/src/sap/fe/core/converters/TemplateConverter.js +1 -1
- package/src/sap/fe/core/converters/TemplateConverter.ts +2 -2
- package/src/sap/fe/core/converters/annotations/DataField.js +3 -3
- package/src/sap/fe/core/converters/annotations/DataField.ts +1 -1
- 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 +20 -10
- package/src/sap/fe/core/converters/controls/Common/Form.ts +24 -4
- package/src/sap/fe/core/converters/controls/Common/KPI.js +69 -4
- package/src/sap/fe/core/converters/controls/Common/KPI.ts +72 -0
- package/src/sap/fe/core/converters/controls/Common/Table.js +390 -398
- package/src/sap/fe/core/converters/controls/Common/Table.ts +497 -484
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +527 -0
- package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +655 -0
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +489 -37
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +506 -58
- 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 +18 -3
- package/src/sap/fe/core/converters/helpers/Aggregation.ts +28 -5
- 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/objectPage/HeaderAndFooterAction.js +4 -4
- package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +3 -3
- package/src/sap/fe/core/converters/templates/ListReportConverter.js +13 -6
- package/src/sap/fe/core/converters/templates/ListReportConverter.ts +26 -15
- package/src/sap/fe/core/designtime/AppComponent.designtime.js +11 -2
- 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 +39 -28
- package/src/sap/fe/core/formatters/TableFormatter.ts +43 -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 +3 -2
- package/src/sap/fe/core/helpers/AppStartupHelper.js +359 -0
- package/src/sap/fe/core/helpers/AppStartupHelper.ts +391 -0
- package/src/sap/fe/core/helpers/BindingExpression.js +484 -437
- package/src/sap/fe/core/helpers/BindingExpression.ts +480 -463
- package/src/sap/fe/core/helpers/ClassSupport.js +27 -15
- package/src/sap/fe/core/helpers/ClassSupport.ts +31 -20
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +63 -59
- package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +56 -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 +687 -0
- package/src/sap/fe/core/helpers/ModelHelper.js +229 -225
- package/src/sap/fe/core/helpers/ModelHelper.ts +227 -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 +332 -313
- package/src/sap/fe/core/helpers/SemanticDateOperators.ts +330 -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 +30 -3
- package/src/sap/fe/core/library.support.js +12 -5
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +62 -0
- package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +66 -0
- package/src/sap/fe/core/messagebundle.properties +61 -13
- package/src/sap/fe/core/messagebundle_ar.properties +33 -2
- package/src/sap/fe/core/messagebundle_bg.properties +33 -2
- package/src/sap/fe/core/messagebundle_ca.properties +33 -2
- package/src/sap/fe/core/messagebundle_cs.properties +34 -3
- package/src/sap/fe/core/messagebundle_cy.properties +33 -2
- package/src/sap/fe/core/messagebundle_da.properties +33 -2
- package/src/sap/fe/core/messagebundle_de.properties +33 -2
- package/src/sap/fe/core/messagebundle_el.properties +33 -2
- package/src/sap/fe/core/messagebundle_en.properties +32 -1
- package/src/sap/fe/core/messagebundle_en_GB.properties +32 -1
- package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +36 -1
- package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +33 -2
- package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +33 -2
- package/src/sap/fe/core/messagebundle_es.properties +33 -2
- package/src/sap/fe/core/messagebundle_es_MX.properties +33 -2
- package/src/sap/fe/core/messagebundle_et.properties +33 -2
- package/src/sap/fe/core/messagebundle_fi.properties +34 -3
- package/src/sap/fe/core/messagebundle_fr.properties +38 -7
- package/src/sap/fe/core/messagebundle_fr_CA.properties +33 -2
- package/src/sap/fe/core/messagebundle_hi.properties +33 -2
- package/src/sap/fe/core/messagebundle_hr.properties +33 -2
- package/src/sap/fe/core/messagebundle_hu.properties +34 -3
- package/src/sap/fe/core/messagebundle_id.properties +36 -5
- package/src/sap/fe/core/messagebundle_it.properties +33 -2
- package/src/sap/fe/core/messagebundle_iw.properties +33 -2
- package/src/sap/fe/core/messagebundle_ja.properties +33 -2
- package/src/sap/fe/core/messagebundle_kk.properties +33 -2
- package/src/sap/fe/core/messagebundle_ko.properties +33 -2
- package/src/sap/fe/core/messagebundle_lt.properties +33 -2
- package/src/sap/fe/core/messagebundle_lv.properties +33 -2
- package/src/sap/fe/core/messagebundle_ms.properties +33 -2
- package/src/sap/fe/core/messagebundle_nl.properties +33 -2
- package/src/sap/fe/core/messagebundle_no.properties +33 -2
- package/src/sap/fe/core/messagebundle_pl.properties +33 -2
- package/src/sap/fe/core/messagebundle_pt.properties +34 -3
- package/src/sap/fe/core/messagebundle_pt_PT.properties +33 -2
- package/src/sap/fe/core/messagebundle_ro.properties +33 -2
- package/src/sap/fe/core/messagebundle_ru.properties +33 -2
- package/src/sap/fe/core/messagebundle_sh.properties +33 -2
- package/src/sap/fe/core/messagebundle_sk.properties +33 -2
- package/src/sap/fe/core/messagebundle_sl.properties +33 -2
- package/src/sap/fe/core/messagebundle_sv.properties +34 -3
- package/src/sap/fe/core/messagebundle_th.properties +33 -2
- package/src/sap/fe/core/messagebundle_tr.properties +33 -2
- package/src/sap/fe/core/messagebundle_uk.properties +33 -2
- package/src/sap/fe/core/messagebundle_vi.properties +33 -2
- package/src/sap/fe/core/messagebundle_zh_CN.properties +33 -2
- package/src/sap/fe/core/messagebundle_zh_TW.properties +33 -2
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +2 -2
- package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +3 -1
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +269 -202
- package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +212 -0
- package/src/sap/fe/core/services/EnvironmentServiceFactory.js +4 -3
- package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +9 -5
- package/src/sap/fe/core/services/NavigationServiceFactory.js +406 -300
- package/src/sap/fe/core/services/NavigationServiceFactory.ts +316 -0
- package/src/sap/fe/core/services/ResourceModelServiceFactory.js +149 -81
- package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +80 -0
- package/src/sap/fe/core/services/RoutingServiceFactory.js +987 -1152
- package/src/sap/fe/core/services/RoutingServiceFactory.ts +898 -0
- package/src/sap/fe/core/services/ShellServicesFactory.js +31 -2
- package/src/sap/fe/core/services/ShellServicesFactory.ts +45 -11
- package/src/sap/fe/core/services/SideEffectsServiceFactory.js +42 -85
- package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +57 -100
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +461 -478
- package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +453 -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/InvalidAnnotationColumnKey.support.js +38 -0
- package/src/sap/fe/core/support/InvalidAnnotationColumnKey.support.ts +18 -0
- package/src/sap/fe/core/templating/DataModelPathHelper.js +10 -48
- package/src/sap/fe/core/templating/DataModelPathHelper.ts +14 -46
- 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 +139 -70
- package/src/sap/fe/core/templating/FilterHelper.ts +140 -70
- package/src/sap/fe/core/templating/PropertyHelper.js +2 -2
- package/src/sap/fe/core/templating/PropertyHelper.ts +1 -1
- package/src/sap/fe/core/templating/UIFormatters.js +45 -110
- package/src/sap/fe/core/templating/UIFormatters.ts +39 -75
- 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,2078 @@
|
|
|
1
|
+
import View from "sap/ui/core/mvc/View";
|
|
2
|
+
import Component from "sap/ui/core/Component";
|
|
3
|
+
import MessageBox from "sap/m/MessageBox";
|
|
4
|
+
import Log from "sap/base/Log";
|
|
5
|
+
import library from "sap/fe/core/library";
|
|
6
|
+
import ModelHelper from "sap/fe/core/helpers/ModelHelper";
|
|
7
|
+
import SemanticDateOperators from "sap/fe/core/helpers/SemanticDateOperators";
|
|
8
|
+
import mergeObjects from "sap/base/util/merge";
|
|
9
|
+
import DataLossOrDraftDiscardHandler from "sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler";
|
|
10
|
+
import XMLTemplateProcessor from "sap/ui/core/XMLTemplateProcessor";
|
|
11
|
+
import XMLPreprocessor from "sap/ui/core/util/XMLPreprocessor";
|
|
12
|
+
import Fragment from "sap/ui/core/Fragment";
|
|
13
|
+
import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
|
|
14
|
+
import ResourceBundle from "sap/base/i18n/ResourceBundle";
|
|
15
|
+
import { bindingExpression, compileBinding, constant, transformRecursively } from "sap/fe/core/helpers/BindingExpression";
|
|
16
|
+
import { getConditions } from "./templating/FilterHelper";
|
|
17
|
+
import { AppComponent } from "sap/fe/core";
|
|
18
|
+
import JSONModel from "sap/ui/model/json/JSONModel";
|
|
19
|
+
import { generate } from "sap/fe/core/helpers/StableIdHelper";
|
|
20
|
+
import ODataModel from "sap/ui/model/odata/v4/ODataModel";
|
|
21
|
+
import Control from "sap/ui/core/Control";
|
|
22
|
+
import FilterOperatorUtil from "sap/ui/mdc/condition/FilterOperatorUtil";
|
|
23
|
+
import TypeUtil from "sap/ui/mdc/odata/v4/TypeUtil";
|
|
24
|
+
import { IssueCategory, IssueSeverity, IssueCategoryType } from "sap/fe/core/converters/helpers/IssueManager";
|
|
25
|
+
|
|
26
|
+
const ProgrammingModel = library.ProgrammingModel;
|
|
27
|
+
const aValidTypes = [
|
|
28
|
+
"Edm.Boolean",
|
|
29
|
+
"Edm.Byte",
|
|
30
|
+
"Edm.Date",
|
|
31
|
+
"Edm.DateTime",
|
|
32
|
+
"Edm.DateTimeOffset",
|
|
33
|
+
"Edm.Decimal",
|
|
34
|
+
"Edm.Double",
|
|
35
|
+
"Edm.Float",
|
|
36
|
+
"Edm.Guid",
|
|
37
|
+
"Edm.Int16",
|
|
38
|
+
"Edm.Int32",
|
|
39
|
+
"Edm.Int64",
|
|
40
|
+
"Edm.SByte",
|
|
41
|
+
"Edm.Single",
|
|
42
|
+
"Edm.String",
|
|
43
|
+
"Edm.Time",
|
|
44
|
+
"Edm.TimeOfDay"
|
|
45
|
+
];
|
|
46
|
+
function normalizeSearchTerm(sSearchTerm: string) {
|
|
47
|
+
if (!sSearchTerm) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return sSearchTerm
|
|
52
|
+
.replace(/"/g, " ")
|
|
53
|
+
.split(/\s+/)
|
|
54
|
+
.reduce(function(sNormalized: string | undefined, sCurrentWord: string) {
|
|
55
|
+
if (sCurrentWord !== "") {
|
|
56
|
+
sNormalized = (sNormalized ? sNormalized + " " : "") + '"' + sCurrentWord + '"';
|
|
57
|
+
}
|
|
58
|
+
return sNormalized;
|
|
59
|
+
}, undefined);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getPropertyDataType(oNavigationContext: any) {
|
|
63
|
+
let sDataType = oNavigationContext.getProperty("$Type");
|
|
64
|
+
// if $kind exists, it's not a DataField and we have the final type already
|
|
65
|
+
if (!oNavigationContext.getProperty("$kind")) {
|
|
66
|
+
switch (sDataType) {
|
|
67
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForAction":
|
|
68
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation":
|
|
69
|
+
sDataType = undefined;
|
|
70
|
+
break;
|
|
71
|
+
|
|
72
|
+
case "com.sap.vocabularies.UI.v1.DataField":
|
|
73
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithNavigationPath":
|
|
74
|
+
case "com.sap.vocabularies.UI.v1.DataFieldWithUrl":
|
|
75
|
+
sDataType = oNavigationContext.getProperty("Value/$Path/$Type");
|
|
76
|
+
break;
|
|
77
|
+
|
|
78
|
+
case "com.sap.vocabularies.UI.v1.DataFieldForAnnotation":
|
|
79
|
+
default:
|
|
80
|
+
const sAnnotationPath = oNavigationContext.getProperty("Target/$AnnotationPath");
|
|
81
|
+
if (sAnnotationPath) {
|
|
82
|
+
if (sAnnotationPath.indexOf("com.sap.vocabularies.Communication.v1.Contact") > -1) {
|
|
83
|
+
sDataType = oNavigationContext.getProperty("Target/$AnnotationPath/fn/$Path/$Type");
|
|
84
|
+
} else if (sAnnotationPath.indexOf("com.sap.vocabularies.UI.v1.DataPoint") > -1) {
|
|
85
|
+
sDataType = oNavigationContext.getProperty("Value/$Path/$Type");
|
|
86
|
+
} else {
|
|
87
|
+
// e.g. FieldGroup or Chart
|
|
88
|
+
sDataType = undefined;
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
sDataType = undefined;
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return sDataType;
|
|
98
|
+
}
|
|
99
|
+
function fnHasTransientContexts(oListBinding: any) {
|
|
100
|
+
let bHasTransientContexts = false;
|
|
101
|
+
if (oListBinding) {
|
|
102
|
+
oListBinding.getCurrentContexts().forEach(function(oContext: any) {
|
|
103
|
+
if (oContext && oContext.isTransient()) {
|
|
104
|
+
bHasTransientContexts = true;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return bHasTransientContexts;
|
|
109
|
+
}
|
|
110
|
+
function getSearchRestrictions(sFullPath: any, oMetaModel: any) {
|
|
111
|
+
let i = 0;
|
|
112
|
+
const aNavigationParts = sFullPath.split("/$NavigationPropertyBinding/");
|
|
113
|
+
for (let sPath = aNavigationParts[0]; i < aNavigationParts.length - 1; i++) {
|
|
114
|
+
const oNavigationRestrictions = getNavigationRestrictions(oMetaModel, sPath, aNavigationParts[i + 1]);
|
|
115
|
+
if (oNavigationRestrictions && oNavigationRestrictions["SearchRestrictions"]) {
|
|
116
|
+
return oNavigationRestrictions["SearchRestrictions"];
|
|
117
|
+
}
|
|
118
|
+
sPath = sPath + "/$NavigationPropertyBinding/" + aNavigationParts[i];
|
|
119
|
+
}
|
|
120
|
+
return oMetaModel.getObject(sFullPath + "@Org.OData.Capabilities.V1.SearchRestrictions");
|
|
121
|
+
}
|
|
122
|
+
function getNavigationRestrictions(oModel: any, sEntitySetPath: any, sNavigationPath: any) {
|
|
123
|
+
const oNavigationRestrictions = oModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.NavigationRestrictions");
|
|
124
|
+
const aRestrictedProperties = oNavigationRestrictions && oNavigationRestrictions.RestrictedProperties;
|
|
125
|
+
return (
|
|
126
|
+
aRestrictedProperties &&
|
|
127
|
+
aRestrictedProperties.find(function(oRestrictedProperty: any) {
|
|
128
|
+
return (
|
|
129
|
+
oRestrictedProperty &&
|
|
130
|
+
oRestrictedProperty.NavigationProperty &&
|
|
131
|
+
oRestrictedProperty.NavigationProperty.$NavigationPropertyPath === sNavigationPath
|
|
132
|
+
);
|
|
133
|
+
})
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
function _isInNonFilterableProperties(oModel: any, sEntitySetPath: any, sContextPath: any) {
|
|
137
|
+
let bIsNotFilterable = false;
|
|
138
|
+
const oAnnotation = oModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.FilterRestrictions");
|
|
139
|
+
if (oAnnotation && oAnnotation.NonFilterableProperties) {
|
|
140
|
+
bIsNotFilterable = oAnnotation.NonFilterableProperties.some(function(property: any) {
|
|
141
|
+
return property.$NavigationPropertyPath === sContextPath || property.$PropertyPath === sContextPath;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
return bIsNotFilterable;
|
|
145
|
+
}
|
|
146
|
+
// TODO rework this!
|
|
147
|
+
function _isContextPathFilterable(oModel: any, sEntitySetPath: any, sContexPath: any) {
|
|
148
|
+
const sFullPath = sEntitySetPath + "/" + sContexPath,
|
|
149
|
+
aESParts = sFullPath.split("/").splice(0, 2),
|
|
150
|
+
aContext = sFullPath.split("/").splice(2);
|
|
151
|
+
let bIsNotFilterable = false,
|
|
152
|
+
sContext = "";
|
|
153
|
+
|
|
154
|
+
sEntitySetPath = aESParts.join("/");
|
|
155
|
+
|
|
156
|
+
bIsNotFilterable = aContext.some(function(item: string, index: number, array: string[]) {
|
|
157
|
+
if (sContext.length > 0) {
|
|
158
|
+
sContext += "/" + item;
|
|
159
|
+
} else {
|
|
160
|
+
sContext = item;
|
|
161
|
+
}
|
|
162
|
+
if (index === array.length - 2) {
|
|
163
|
+
// In case of "/Customer/Set/Property" this is to check navigation restrictions of "Customer" for non-filterable properties in "Set"
|
|
164
|
+
const oNavigationRestrictions = getNavigationRestrictions(oModel, sEntitySetPath, item);
|
|
165
|
+
const oFilterRestrictions = oNavigationRestrictions && oNavigationRestrictions.FilterRestrictions;
|
|
166
|
+
const aNonFilterableProperties = oFilterRestrictions && oFilterRestrictions.NonFilterableProperties;
|
|
167
|
+
const sTargetPropertyPath = array[array.length - 1];
|
|
168
|
+
if (
|
|
169
|
+
aNonFilterableProperties &&
|
|
170
|
+
aNonFilterableProperties.find(function(oPropertyPath: any) {
|
|
171
|
+
return oPropertyPath.$PropertyPath === sTargetPropertyPath;
|
|
172
|
+
})
|
|
173
|
+
) {
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (index === array.length - 1) {
|
|
178
|
+
//last path segment
|
|
179
|
+
bIsNotFilterable = _isInNonFilterableProperties(oModel, sEntitySetPath, sContext);
|
|
180
|
+
} else if (oModel.getObject(sEntitySetPath + "/$NavigationPropertyBinding/" + item)) {
|
|
181
|
+
//check existing context path and initialize it
|
|
182
|
+
bIsNotFilterable = _isInNonFilterableProperties(oModel, sEntitySetPath, sContext);
|
|
183
|
+
sContext = "";
|
|
184
|
+
//set the new EntitySet
|
|
185
|
+
sEntitySetPath = "/" + oModel.getObject(sEntitySetPath + "/$NavigationPropertyBinding/" + item);
|
|
186
|
+
}
|
|
187
|
+
return bIsNotFilterable === true;
|
|
188
|
+
});
|
|
189
|
+
return bIsNotFilterable;
|
|
190
|
+
}
|
|
191
|
+
// TODO check used places and rework this
|
|
192
|
+
function isPropertyFilterable(oModel: ODataMetaModel, sEntitySetPath: string, sProperty: string, bSkipHiddenFilter: boolean) {
|
|
193
|
+
if (typeof sProperty !== "string") {
|
|
194
|
+
throw new Error("sProperty parameter must be a string");
|
|
195
|
+
}
|
|
196
|
+
let bIsFilterable;
|
|
197
|
+
|
|
198
|
+
// Parameters should be rendered as filterfields
|
|
199
|
+
if (oModel.getProperty(sEntitySetPath + "/@com.sap.vocabularies.Common.v1.ResultContext") === true) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const oNavigationContext = oModel.createBindingContext(sEntitySetPath + "/" + sProperty);
|
|
204
|
+
|
|
205
|
+
if (oNavigationContext.getProperty("@com.sap.vocabularies.UI.v1.Hidden") === true) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!bSkipHiddenFilter && oNavigationContext.getProperty("@com.sap.vocabularies.UI.v1.HiddenFilter")) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (sEntitySetPath.split("/").length === 2 && sProperty.indexOf("/") < 0) {
|
|
214
|
+
// there is no navigation in entitySet path and property path
|
|
215
|
+
bIsFilterable = !_isInNonFilterableProperties(oModel, sEntitySetPath, sProperty);
|
|
216
|
+
} else {
|
|
217
|
+
bIsFilterable = !_isContextPathFilterable(oModel, sEntitySetPath, sProperty);
|
|
218
|
+
}
|
|
219
|
+
// check if type can be used for filtering
|
|
220
|
+
if (bIsFilterable && oNavigationContext) {
|
|
221
|
+
const sPropertyDataType = getPropertyDataType(oNavigationContext);
|
|
222
|
+
if (sPropertyDataType) {
|
|
223
|
+
bIsFilterable = aValidTypes.indexOf(sPropertyDataType) !== -1;
|
|
224
|
+
} else {
|
|
225
|
+
bIsFilterable = false;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return bIsFilterable;
|
|
230
|
+
}
|
|
231
|
+
function getShellServices(oControl: any) {
|
|
232
|
+
return getAppComponent(oControl).getShellServices();
|
|
233
|
+
}
|
|
234
|
+
function getHash() {
|
|
235
|
+
const sHash = window.location.hash;
|
|
236
|
+
return sHash.split("&")[0];
|
|
237
|
+
}
|
|
238
|
+
function _getSOIntents(oObjectPageLayout: any, oSemanticObject: any, oParam: any) {
|
|
239
|
+
const oShellServiceHelper = CommonUtils.getShellServices(oObjectPageLayout);
|
|
240
|
+
return oShellServiceHelper.getLinks({
|
|
241
|
+
semanticObject: oSemanticObject,
|
|
242
|
+
params: oParam
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
// TO-DO add this as part of applySemanticObjectmappings logic in IntentBasednavigation controller extension
|
|
246
|
+
function _createMappings(oMapping: any) {
|
|
247
|
+
const aSOMappings = [];
|
|
248
|
+
const aMappingKeys = Object.keys(oMapping);
|
|
249
|
+
let oSemanticMapping;
|
|
250
|
+
for (let i = 0; i < aMappingKeys.length; i++) {
|
|
251
|
+
oSemanticMapping = {
|
|
252
|
+
"LocalProperty": {
|
|
253
|
+
"$PropertyPath": aMappingKeys[i]
|
|
254
|
+
},
|
|
255
|
+
"SemanticObjectProperty": oMapping[aMappingKeys[i]]
|
|
256
|
+
};
|
|
257
|
+
aSOMappings.push(oSemanticMapping);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return aSOMappings;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* @param aLinks
|
|
264
|
+
* @param aExcludedActions
|
|
265
|
+
* @param oTargetParams
|
|
266
|
+
* @param aItems
|
|
267
|
+
*/
|
|
268
|
+
function _getRelatedAppsMenuItems(aLinks: any, aExcludedActions: any, oTargetParams: any, aItems: any) {
|
|
269
|
+
for (let i = 0; i < aLinks.length; i++) {
|
|
270
|
+
const oLink = aLinks[i];
|
|
271
|
+
const sIntent = oLink.intent;
|
|
272
|
+
const sAction = sIntent.split("-")[1].split("?")[0];
|
|
273
|
+
if (aExcludedActions && aExcludedActions.indexOf(sAction) === -1) {
|
|
274
|
+
aItems.push({
|
|
275
|
+
text: oLink.text,
|
|
276
|
+
targetSemObject: sIntent.split("#")[1].split("-")[0],
|
|
277
|
+
targetAction: sAction.split("~")[0],
|
|
278
|
+
targetParams: oTargetParams
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* @param oAdditionalSemanticObjects
|
|
285
|
+
* @param oBindingContext
|
|
286
|
+
* @param aManifestSOItems
|
|
287
|
+
* @param aLinks
|
|
288
|
+
*/
|
|
289
|
+
function _getRelatedIntents(oAdditionalSemanticObjects: any, oBindingContext: any, aManifestSOItems: any, aLinks: any) {
|
|
290
|
+
if (aLinks && aLinks.length > 0) {
|
|
291
|
+
const aExcludedActions = oAdditionalSemanticObjects.unavailableActions ? oAdditionalSemanticObjects.unavailableActions : [];
|
|
292
|
+
const aSOMappings = oAdditionalSemanticObjects.mapping ? _createMappings(oAdditionalSemanticObjects.mapping) : [];
|
|
293
|
+
const oTargetParams = { navigationContexts: oBindingContext, semanticObjectMapping: aSOMappings };
|
|
294
|
+
_getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aManifestSOItems);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function updateRelateAppsModel(
|
|
298
|
+
this: any,
|
|
299
|
+
oBindingContext: any,
|
|
300
|
+
oEntry: any,
|
|
301
|
+
oObjectPageLayout: any,
|
|
302
|
+
aSemKeys: any,
|
|
303
|
+
oMetaModel: any,
|
|
304
|
+
oMetaPath: any
|
|
305
|
+
) {
|
|
306
|
+
const oShellServiceHelper = getShellServices(oObjectPageLayout);
|
|
307
|
+
const oParam: any = {};
|
|
308
|
+
let sCurrentSemObj = "",
|
|
309
|
+
sCurrentAction = "";
|
|
310
|
+
let oSemanticObjectAnnotations;
|
|
311
|
+
let aRelatedAppsMenuItems: any[] = [];
|
|
312
|
+
let aExcludedActions: any[] = [];
|
|
313
|
+
|
|
314
|
+
if (oEntry) {
|
|
315
|
+
if (aSemKeys && aSemKeys.length > 0) {
|
|
316
|
+
for (let j = 0; j < aSemKeys.length; j++) {
|
|
317
|
+
const sSemKey = aSemKeys[j].$PropertyPath;
|
|
318
|
+
if (!oParam[sSemKey]) {
|
|
319
|
+
oParam[sSemKey] = { value: oEntry[sSemKey] };
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
// fallback to Technical Keys if no Semantic Key is present
|
|
324
|
+
const aTechnicalKeys = oMetaModel.getObject(oMetaPath + "/$Type/$Key");
|
|
325
|
+
for (const key in aTechnicalKeys) {
|
|
326
|
+
const sObjKey = aTechnicalKeys[key];
|
|
327
|
+
if (!oParam[sObjKey]) {
|
|
328
|
+
oParam[sObjKey] = { value: oEntry[sObjKey] };
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// Logic to read additional SO from manifest and updated relatedapps model
|
|
334
|
+
|
|
335
|
+
const oManifestData = getTargetView(oObjectPageLayout).getViewData();
|
|
336
|
+
const aManifestSOItems: any[] = [];
|
|
337
|
+
if (oManifestData.additionalSemanticObjects) {
|
|
338
|
+
const aManifestSOKeys = Object.keys(oManifestData.additionalSemanticObjects);
|
|
339
|
+
for (let key = 0; key < aManifestSOKeys.length; key++) {
|
|
340
|
+
_getSOIntents(oObjectPageLayout, aManifestSOKeys[key], oParam)
|
|
341
|
+
.then(
|
|
342
|
+
_getRelatedIntents.bind(
|
|
343
|
+
this as any,
|
|
344
|
+
oManifestData.additionalSemanticObjects[aManifestSOKeys[key]],
|
|
345
|
+
oBindingContext,
|
|
346
|
+
aManifestSOItems
|
|
347
|
+
)
|
|
348
|
+
)
|
|
349
|
+
.catch(function(oError: any) {
|
|
350
|
+
Log.error("Error while retrieving SO Intents", oError);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function fnGetParseShellHashAndGetLinks() {
|
|
356
|
+
const oParsedUrl = oShellServiceHelper.parseShellHash(document.location.hash);
|
|
357
|
+
sCurrentSemObj = oParsedUrl.semanticObject; // Current Semantic Object
|
|
358
|
+
sCurrentAction = oParsedUrl.action;
|
|
359
|
+
return _getSOIntents(oObjectPageLayout, sCurrentSemObj, oParam);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
fnGetParseShellHashAndGetLinks()
|
|
363
|
+
.then(function(aLinks: any) {
|
|
364
|
+
if (aLinks && aLinks.length > 0) {
|
|
365
|
+
const oTargetParams: any = {};
|
|
366
|
+
const aAnnotationsSOItems: any[] = [];
|
|
367
|
+
const sEntitySetPath = oMetaPath + "@";
|
|
368
|
+
const sEntityTypePath = oMetaPath + "/@";
|
|
369
|
+
const oEntitySetAnnotations = oMetaModel.getObject(sEntitySetPath);
|
|
370
|
+
oSemanticObjectAnnotations = _getSemanticObjectAnnotations(oEntitySetAnnotations, sCurrentSemObj);
|
|
371
|
+
if (!oSemanticObjectAnnotations.bHasEntitySetSO) {
|
|
372
|
+
const oEntityTypeAnnotations = oMetaModel.getObject(sEntityTypePath);
|
|
373
|
+
oSemanticObjectAnnotations = _getSemanticObjectAnnotations(oEntityTypeAnnotations, sCurrentSemObj);
|
|
374
|
+
}
|
|
375
|
+
aExcludedActions = oSemanticObjectAnnotations.aUnavailableActions;
|
|
376
|
+
//Skip same application from Related Apps
|
|
377
|
+
aExcludedActions.push(sCurrentAction);
|
|
378
|
+
oTargetParams.navigationContexts = oBindingContext;
|
|
379
|
+
oTargetParams.semanticObjectMapping = oSemanticObjectAnnotations.aMappings;
|
|
380
|
+
_getRelatedAppsMenuItems(aLinks, aExcludedActions, oTargetParams, aAnnotationsSOItems);
|
|
381
|
+
aRelatedAppsMenuItems = aAnnotationsSOItems.concat(aManifestSOItems);
|
|
382
|
+
// If no app in list, related apps button will be hidden
|
|
383
|
+
oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/visibility", aRelatedAppsMenuItems.length > 0);
|
|
384
|
+
oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/items", aRelatedAppsMenuItems);
|
|
385
|
+
} else {
|
|
386
|
+
oObjectPageLayout.getBindingContext("internal").setProperty("relatedApps/visibility", false);
|
|
387
|
+
}
|
|
388
|
+
})
|
|
389
|
+
.catch(function(oError: any) {
|
|
390
|
+
Log.error("Cannot read links", oError);
|
|
391
|
+
});
|
|
392
|
+
return aRelatedAppsMenuItems;
|
|
393
|
+
}
|
|
394
|
+
function _getSemanticObjectAnnotations(oEntityAnnotations: any, sCurrentSemObj: any) {
|
|
395
|
+
const oSemanticObjectAnnotations = {
|
|
396
|
+
bHasEntitySetSO: false,
|
|
397
|
+
aUnavailableActions: [],
|
|
398
|
+
aMappings: []
|
|
399
|
+
};
|
|
400
|
+
let sAnnotationMappingTerm, sAnnotationActionTerm;
|
|
401
|
+
let sQualifier;
|
|
402
|
+
for (const key in oEntityAnnotations) {
|
|
403
|
+
if (key.indexOf("com.sap.vocabularies.Common.v1.SemanticObject") > -1 && oEntityAnnotations[key] === sCurrentSemObj) {
|
|
404
|
+
oSemanticObjectAnnotations.bHasEntitySetSO = true;
|
|
405
|
+
sAnnotationMappingTerm = "@com.sap.vocabularies.Common.v1.SemanticObjectMapping";
|
|
406
|
+
sAnnotationActionTerm = "@com.sap.vocabularies.Common.v1.SemanticObjectUnavailableActions";
|
|
407
|
+
|
|
408
|
+
if (key.indexOf("#") > -1) {
|
|
409
|
+
sQualifier = key.split("#")[1];
|
|
410
|
+
sAnnotationMappingTerm = sAnnotationMappingTerm + "#" + sQualifier;
|
|
411
|
+
sAnnotationActionTerm = sAnnotationActionTerm + "#" + sQualifier;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
oSemanticObjectAnnotations.aMappings = oSemanticObjectAnnotations.aMappings.concat(oEntityAnnotations[sAnnotationMappingTerm]);
|
|
415
|
+
oSemanticObjectAnnotations.aUnavailableActions = oSemanticObjectAnnotations.aUnavailableActions.concat(
|
|
416
|
+
oEntityAnnotations[sAnnotationActionTerm]
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return oSemanticObjectAnnotations;
|
|
423
|
+
}
|
|
424
|
+
function fnUpdateRelatedAppsDetails(oObjectPageLayout: any) {
|
|
425
|
+
const oMetaModel = oObjectPageLayout.getModel().getMetaModel();
|
|
426
|
+
const oBindingContext = oObjectPageLayout.getBindingContext();
|
|
427
|
+
const oPath = oBindingContext && oBindingContext.getPath();
|
|
428
|
+
const oMetaPath = oMetaModel.getMetaPath(oPath);
|
|
429
|
+
// Semantic Key Vocabulary
|
|
430
|
+
const sSemanticKeyVocabulary = oMetaPath + "/" + "@com.sap.vocabularies.Common.v1.SemanticKey";
|
|
431
|
+
//Semantic Keys
|
|
432
|
+
const aSemKeys = oMetaModel.getObject(sSemanticKeyVocabulary);
|
|
433
|
+
// Unavailable Actions
|
|
434
|
+
const oEntry = oBindingContext.getObject();
|
|
435
|
+
if (!oEntry) {
|
|
436
|
+
oBindingContext
|
|
437
|
+
.requestObject()
|
|
438
|
+
.then(function(oEntry: any) {
|
|
439
|
+
return updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath);
|
|
440
|
+
})
|
|
441
|
+
.catch(function(oError: any) {
|
|
442
|
+
Log.error("Cannot update the related app details", oError);
|
|
443
|
+
});
|
|
444
|
+
} else {
|
|
445
|
+
return updateRelateAppsModel(oBindingContext, oEntry, oObjectPageLayout, aSemKeys, oMetaModel, oMetaPath);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* @param oButton
|
|
450
|
+
*/
|
|
451
|
+
function fnFireButtonPress(oButton: any) {
|
|
452
|
+
const aAuthorizedTypes = ["sap.m.Button", "sap.m.OverflowToolbarButton"];
|
|
453
|
+
if (oButton && aAuthorizedTypes.indexOf(oButton.getMetadata().getName()) !== -1 && oButton.getVisible() && oButton.getEnabled()) {
|
|
454
|
+
oButton.firePress();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function fnResolveStringtoBoolean(sValue: any) {
|
|
458
|
+
if (sValue === "true" || sValue === true) {
|
|
459
|
+
return true;
|
|
460
|
+
} else {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function getAppComponent(oControl: any): AppComponent {
|
|
465
|
+
if (oControl.isA("sap.fe.core.AppComponent")) {
|
|
466
|
+
return oControl;
|
|
467
|
+
}
|
|
468
|
+
const oOwner = Component.getOwnerComponentFor(oControl);
|
|
469
|
+
if (!oOwner) {
|
|
470
|
+
return oControl;
|
|
471
|
+
} else {
|
|
472
|
+
return getAppComponent(oOwner);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
function getTargetView(oControl: any) {
|
|
476
|
+
if (oControl && oControl.isA("sap.ui.core.ComponentContainer")) {
|
|
477
|
+
oControl = oControl.getComponentInstance();
|
|
478
|
+
oControl = oControl && oControl.getRootControl();
|
|
479
|
+
}
|
|
480
|
+
while (oControl && !(oControl instanceof View)) {
|
|
481
|
+
oControl = oControl.getParent();
|
|
482
|
+
}
|
|
483
|
+
return oControl;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* @param fnProcessFunction
|
|
487
|
+
* @param fnCancelFunction
|
|
488
|
+
* @param oContext
|
|
489
|
+
* @param oController
|
|
490
|
+
* @param bSkipBindingToView
|
|
491
|
+
*/
|
|
492
|
+
function fnProcessDataLossOrDraftDiscardConfirmation(
|
|
493
|
+
fnProcessFunction: any,
|
|
494
|
+
fnCancelFunction: any,
|
|
495
|
+
oContext: any,
|
|
496
|
+
oController: any,
|
|
497
|
+
bSkipBindingToView: any
|
|
498
|
+
) {
|
|
499
|
+
const oModel = oContext.getModel();
|
|
500
|
+
let _bIsModified = false;
|
|
501
|
+
const draftDataContext = oModel.bindContext(oContext.getPath() + "/DraftAdministrativeData").getBoundContext();
|
|
502
|
+
if (
|
|
503
|
+
oContext &&
|
|
504
|
+
oContext.getObject() &&
|
|
505
|
+
(!oContext.getObject().DraftAdministrativeData || oContext.getObject().IsActiveEntity === true)
|
|
506
|
+
) {
|
|
507
|
+
fnProcessFunction();
|
|
508
|
+
} else {
|
|
509
|
+
draftDataContext
|
|
510
|
+
.requestObject()
|
|
511
|
+
.then(function(draftAdminData: any) {
|
|
512
|
+
if (draftAdminData) {
|
|
513
|
+
_bIsModified = !(draftAdminData.CreationDateTime === draftAdminData.LastChangeDateTime);
|
|
514
|
+
if (_bIsModified) {
|
|
515
|
+
DataLossOrDraftDiscardHandler.performAfterDiscardorKeepDraft(
|
|
516
|
+
fnProcessFunction,
|
|
517
|
+
fnCancelFunction,
|
|
518
|
+
oController,
|
|
519
|
+
bSkipBindingToView
|
|
520
|
+
);
|
|
521
|
+
} else {
|
|
522
|
+
fnProcessFunction();
|
|
523
|
+
}
|
|
524
|
+
} else {
|
|
525
|
+
fnProcessFunction();
|
|
526
|
+
}
|
|
527
|
+
})
|
|
528
|
+
.catch(function(oError: any) {
|
|
529
|
+
Log.error("Cannot retrieve draftDataContext information", oError);
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
function fnProcessDataLossConfirmation(fnProcess: Function, oControl: any, programmingModel: string) {
|
|
534
|
+
const bUIEditable = oControl.getModel("ui").getProperty("/isEditable"),
|
|
535
|
+
oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.templates") as ResourceBundle,
|
|
536
|
+
sWarningMsg = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_MSG"),
|
|
537
|
+
sConfirmButtonTxt = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_CONFIRM_BUTTON"),
|
|
538
|
+
sCancelButtonTxt = oResourceBundle && oResourceBundle.getText("T_COMMON_UTILS_NAVIGATION_AWAY_CANCEL_BUTTON");
|
|
539
|
+
|
|
540
|
+
if (programmingModel === ProgrammingModel.Sticky && bUIEditable) {
|
|
541
|
+
return MessageBox.warning(sWarningMsg, {
|
|
542
|
+
actions: [sConfirmButtonTxt, sCancelButtonTxt],
|
|
543
|
+
onClose: function(sAction: any) {
|
|
544
|
+
if (sAction === sConfirmButtonTxt) {
|
|
545
|
+
const oInternalModel = oControl && oControl.getModel("internal");
|
|
546
|
+
|
|
547
|
+
Log.info("Navigation confirmed.");
|
|
548
|
+
if (oInternalModel) {
|
|
549
|
+
oInternalModel.setProperty("/sessionOn", false);
|
|
550
|
+
} else {
|
|
551
|
+
Log.warning("Local UIModel couldn't be found.");
|
|
552
|
+
}
|
|
553
|
+
fnProcess();
|
|
554
|
+
} else {
|
|
555
|
+
Log.info("Navigation rejected.");
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
return fnProcess();
|
|
561
|
+
}
|
|
562
|
+
function isFieldControlPathInapplicable(sFieldControlPath: string, oAttribute: any) {
|
|
563
|
+
let bInapplicable = false;
|
|
564
|
+
const aParts = sFieldControlPath.split("/");
|
|
565
|
+
// sensitive data is removed only if the path has already been resolved.
|
|
566
|
+
if (aParts.length > 1) {
|
|
567
|
+
bInapplicable = oAttribute[aParts[0]] && oAttribute[aParts[0]].hasOwnProperty(aParts[1]) && oAttribute[aParts[0]][aParts[1]] === 0;
|
|
568
|
+
} else {
|
|
569
|
+
bInapplicable = oAttribute[sFieldControlPath] === 0;
|
|
570
|
+
}
|
|
571
|
+
return bInapplicable;
|
|
572
|
+
}
|
|
573
|
+
function removeSensitiveData(aAttributes: any[], oMetaModel: ODataMetaModel) {
|
|
574
|
+
const aOutAttributes = [];
|
|
575
|
+
for (let i = 0; i < aAttributes.length; i++) {
|
|
576
|
+
const sEntitySet = aAttributes[i].entitySet,
|
|
577
|
+
oAttribute = aAttributes[i].contextData;
|
|
578
|
+
|
|
579
|
+
delete oAttribute["@odata.context"];
|
|
580
|
+
delete oAttribute["%40odata.context"];
|
|
581
|
+
delete oAttribute["@odata.metadataEtag"];
|
|
582
|
+
delete oAttribute["%40odata.metadataEtag"];
|
|
583
|
+
delete oAttribute["SAP__Messages"];
|
|
584
|
+
const aProperties = Object.keys(oAttribute);
|
|
585
|
+
for (let j = 0; j < aProperties.length; j++) {
|
|
586
|
+
const sProp = aProperties[j],
|
|
587
|
+
aPropertyAnnotations = oMetaModel.getObject("/" + sEntitySet + "/" + sProp + "@");
|
|
588
|
+
if (aPropertyAnnotations) {
|
|
589
|
+
if (
|
|
590
|
+
aPropertyAnnotations["@com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive"] ||
|
|
591
|
+
aPropertyAnnotations["@com.sap.vocabularies.UI.v1.ExcludeFromNavigationContext"] ||
|
|
592
|
+
aPropertyAnnotations["@com.sap.vocabularies.Analytics.v1.Measure"]
|
|
593
|
+
) {
|
|
594
|
+
delete oAttribute[sProp];
|
|
595
|
+
} else if (aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"]) {
|
|
596
|
+
const oFieldControl = aPropertyAnnotations["@com.sap.vocabularies.Common.v1.FieldControl"];
|
|
597
|
+
if (oFieldControl["$EnumMember"] && oFieldControl["$EnumMember"].split("/")[1] === "Inapplicable") {
|
|
598
|
+
delete oAttribute[sProp];
|
|
599
|
+
} else if (oFieldControl["$Path"] && CommonUtils.isFieldControlPathInapplicable(oFieldControl["$Path"], oAttribute)) {
|
|
600
|
+
delete oAttribute[sProp];
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
aOutAttributes.push(oAttribute);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
return aOutAttributes;
|
|
609
|
+
}
|
|
610
|
+
function _fnCheckIsMatch(oObject: any, oKeysToCheck: any) {
|
|
611
|
+
for (const sKey in oKeysToCheck) {
|
|
612
|
+
if (oKeysToCheck[sKey] !== oObject[sKey]) {
|
|
613
|
+
return false;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
function fnGetContextPathProperties(oMetaModel: ODataMetaModel, sContextPath: string, oFilter?: object) {
|
|
619
|
+
const oEntityType = oMetaModel.getObject(sContextPath + "/") || {},
|
|
620
|
+
oProperties: any = {};
|
|
621
|
+
|
|
622
|
+
for (const sKey in oEntityType) {
|
|
623
|
+
if (
|
|
624
|
+
oEntityType.hasOwnProperty(sKey) &&
|
|
625
|
+
!/^\$/i.test(sKey) &&
|
|
626
|
+
oEntityType[sKey].$kind &&
|
|
627
|
+
_fnCheckIsMatch(oEntityType[sKey], oFilter || { $kind: "Property" })
|
|
628
|
+
) {
|
|
629
|
+
oProperties[sKey] = oEntityType[sKey];
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return oProperties;
|
|
633
|
+
}
|
|
634
|
+
function fnGetMandatoryFilterFields(oMetaModel: ODataMetaModel, sContextPath: string) {
|
|
635
|
+
let aMandatoryFilterFields;
|
|
636
|
+
if (oMetaModel && sContextPath) {
|
|
637
|
+
aMandatoryFilterFields = oMetaModel.getObject(sContextPath + "@Org.OData.Capabilities.V1.FilterRestrictions/RequiredProperties");
|
|
638
|
+
}
|
|
639
|
+
return aMandatoryFilterFields;
|
|
640
|
+
}
|
|
641
|
+
function fnGetIBNActions(oControl: any, aIBNActions: any[]) {
|
|
642
|
+
const aActions = oControl && oControl.getActions();
|
|
643
|
+
if (aActions) {
|
|
644
|
+
aActions.forEach(function(oAction: any) {
|
|
645
|
+
if (oAction.isA("sap.ui.mdc.actiontoolbar.ActionToolbarAction")) {
|
|
646
|
+
oAction = oAction.getAction();
|
|
647
|
+
}
|
|
648
|
+
if (oAction.data("IBNData")) {
|
|
649
|
+
aIBNActions.push(oAction);
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
return aIBNActions;
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* @param aIBNActions
|
|
657
|
+
* @param oView
|
|
658
|
+
*/
|
|
659
|
+
function fnUpdateDataFieldForIBNButtonsVisibility(aIBNActions: any[], oView: View) {
|
|
660
|
+
const oParams: any = {};
|
|
661
|
+
const fnGetLinks = function(oData?: any) {
|
|
662
|
+
if (oData) {
|
|
663
|
+
const aKeys = Object.keys(oData);
|
|
664
|
+
aKeys.forEach(function(sKey: string) {
|
|
665
|
+
if (sKey.indexOf("_") !== 0 && sKey.indexOf("odata.context") === -1) {
|
|
666
|
+
oParams[sKey] = { value: oData[sKey] };
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
if (aIBNActions.length) {
|
|
671
|
+
aIBNActions.forEach(function(oIBNAction: any) {
|
|
672
|
+
const sSemanticObject = oIBNAction.data("IBNData").semanticObject;
|
|
673
|
+
const sAction = oIBNAction.data("IBNData").action;
|
|
674
|
+
CommonUtils.getShellServices(oView)
|
|
675
|
+
.getLinks({
|
|
676
|
+
semanticObject: sSemanticObject,
|
|
677
|
+
action: sAction,
|
|
678
|
+
params: oParams
|
|
679
|
+
})
|
|
680
|
+
.then(function(aLink: any) {
|
|
681
|
+
oIBNAction.setVisible(oIBNAction.getVisible() && aLink && aLink.length === 1);
|
|
682
|
+
})
|
|
683
|
+
.catch(function(oError: any) {
|
|
684
|
+
Log.error("Cannot retrieve the links from the shell service", oError);
|
|
685
|
+
});
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
if (oView && oView.getBindingContext()) {
|
|
690
|
+
(oView.getBindingContext() as any)
|
|
691
|
+
?.requestObject()
|
|
692
|
+
.then(function(oData: any) {
|
|
693
|
+
return fnGetLinks(oData);
|
|
694
|
+
})
|
|
695
|
+
.catch(function(oError: any) {
|
|
696
|
+
Log.error("Cannot retrieve the links from the shell service", oError);
|
|
697
|
+
});
|
|
698
|
+
} else {
|
|
699
|
+
fnGetLinks();
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
function getTranslatedText(sFrameworkKey: string, oResourceBundle: ResourceBundle, oParams?: any, sEntitySetName?: string) {
|
|
703
|
+
let sResourceKey = sFrameworkKey;
|
|
704
|
+
if (oResourceBundle) {
|
|
705
|
+
if (sEntitySetName) {
|
|
706
|
+
// There are console errors logged when making calls to getText for keys that are not defined in the resource bundle
|
|
707
|
+
// for instance keys which are supposed to be provided by the application, e.g, <key>|<entitySet> to override instance specific text
|
|
708
|
+
// hence check if text exists (using "hasText") in the resource bundle before calling "getText"
|
|
709
|
+
|
|
710
|
+
// "hasText" only checks for the key in the immediate resource bundle and not it's custom bundles
|
|
711
|
+
// hence we need to do this recurrsively to check if the key exists in any of the bundles the forms the FE resource bundle
|
|
712
|
+
const bResourceKeyExists = _checkIfResourceKeyExists(
|
|
713
|
+
(oResourceBundle as any).aCustomBundles,
|
|
714
|
+
sFrameworkKey + "|" + sEntitySetName
|
|
715
|
+
);
|
|
716
|
+
|
|
717
|
+
// if resource key with entity set name for instance specific text overriding is provided by the application
|
|
718
|
+
// then use the same key otherwise use the Framework key
|
|
719
|
+
sResourceKey = bResourceKeyExists ? sFrameworkKey + "|" + sEntitySetName : sFrameworkKey;
|
|
720
|
+
}
|
|
721
|
+
return oResourceBundle.getText(sResourceKey, oParams);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// do not allow override so get text from the internal bundle directly
|
|
725
|
+
oResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.fe.core") as ResourceBundle;
|
|
726
|
+
return oResourceBundle.getText(sResourceKey, oParams);
|
|
727
|
+
}
|
|
728
|
+
function _checkIfResourceKeyExists(aCustomBundles: any, sKey: any) {
|
|
729
|
+
if (aCustomBundles.length) {
|
|
730
|
+
for (let i = aCustomBundles.length - 1; i >= 0; i--) {
|
|
731
|
+
const sValue = aCustomBundles[i].hasText(sKey);
|
|
732
|
+
// text found return true
|
|
733
|
+
if (sValue) {
|
|
734
|
+
return true;
|
|
735
|
+
}
|
|
736
|
+
_checkIfResourceKeyExists(aCustomBundles[i].aCustomBundles, sKey);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return false;
|
|
740
|
+
}
|
|
741
|
+
function getActionPath(oAction: any, bReturnOnlyPath: boolean, sActionName?: string, bCheckStaticValue?: boolean) {
|
|
742
|
+
sActionName = !sActionName ? oAction.getObject(oAction.getPath()) : sActionName;
|
|
743
|
+
let sContextPath = oAction.getPath().split("/@")[0];
|
|
744
|
+
const sEntityTypeName = oAction.getObject(sContextPath).$Type;
|
|
745
|
+
const sEntityName = getEntitySetName(oAction.getModel(), sEntityTypeName);
|
|
746
|
+
if (sEntityName) {
|
|
747
|
+
sContextPath = "/" + sEntityName;
|
|
748
|
+
}
|
|
749
|
+
if (bCheckStaticValue) {
|
|
750
|
+
return oAction.getObject(sContextPath + "/" + sActionName + "@Org.OData.Core.V1.OperationAvailable");
|
|
751
|
+
}
|
|
752
|
+
if (bReturnOnlyPath) {
|
|
753
|
+
return sContextPath + "/" + sActionName;
|
|
754
|
+
} else {
|
|
755
|
+
return {
|
|
756
|
+
sContextPath: sContextPath,
|
|
757
|
+
sProperty: oAction.getObject(sContextPath + "/" + sActionName + "@Org.OData.Core.V1.OperationAvailable/$Path"),
|
|
758
|
+
sBindingParameter: oAction.getObject(sContextPath + "/" + sActionName + "/@$ui5.overload/0/$Parameter/0/$Name")
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
function getEntitySetName(oMetaModel: any, sEntityType: any) {
|
|
763
|
+
const oEntityContainer = oMetaModel.getObject("/");
|
|
764
|
+
for (const key in oEntityContainer) {
|
|
765
|
+
if (typeof oEntityContainer[key] === "object" && oEntityContainer[key].$Type === sEntityType) {
|
|
766
|
+
return key;
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
function computeDisplayMode(oPropertyAnnotations: any, oCollectionAnnotations: any) {
|
|
771
|
+
const oTextAnnotation = oPropertyAnnotations["@com.sap.vocabularies.Common.v1.Text"],
|
|
772
|
+
oTextArrangementAnnotation =
|
|
773
|
+
oTextAnnotation &&
|
|
774
|
+
((oPropertyAnnotations &&
|
|
775
|
+
oPropertyAnnotations["@com.sap.vocabularies.Common.v1.Text@com.sap.vocabularies.UI.v1.TextArrangement"]) ||
|
|
776
|
+
(oCollectionAnnotations && oCollectionAnnotations["@com.sap.vocabularies.UI.v1.TextArrangement"]));
|
|
777
|
+
|
|
778
|
+
if (oTextArrangementAnnotation) {
|
|
779
|
+
if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextOnly") {
|
|
780
|
+
return "Description";
|
|
781
|
+
} else if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextLast") {
|
|
782
|
+
return "ValueDescription";
|
|
783
|
+
} else if (oTextArrangementAnnotation.$EnumMember === "com.sap.vocabularies.UI.v1.TextArrangementType/TextSeparate") {
|
|
784
|
+
return "Value";
|
|
785
|
+
}
|
|
786
|
+
//Default should be TextFirst if there is a Text annotation and neither TextOnly nor TextLast are set
|
|
787
|
+
return "DescriptionValue";
|
|
788
|
+
}
|
|
789
|
+
return oTextAnnotation ? "DescriptionValue" : "Value";
|
|
790
|
+
}
|
|
791
|
+
function _getEntityType(oContext: any) {
|
|
792
|
+
const oMetaModel = oContext.getModel().getMetaModel();
|
|
793
|
+
return oMetaModel.getObject(oMetaModel.getMetaPath(oContext.getPath()) + "/$Type");
|
|
794
|
+
}
|
|
795
|
+
function _requestObject(sAction: any, oSelectedContext: any, sProperty: any) {
|
|
796
|
+
let oContext = oSelectedContext;
|
|
797
|
+
const nBracketIndex = sAction.indexOf("(");
|
|
798
|
+
|
|
799
|
+
if (nBracketIndex > -1) {
|
|
800
|
+
const sTargetType = sAction.slice(nBracketIndex + 1, -1);
|
|
801
|
+
let sCurrentType = _getEntityType(oContext);
|
|
802
|
+
|
|
803
|
+
while (sCurrentType !== sTargetType) {
|
|
804
|
+
// Find parent binding context and retrieve entity type
|
|
805
|
+
oContext = oContext.getBinding().getContext();
|
|
806
|
+
if (oContext) {
|
|
807
|
+
sCurrentType = _getEntityType(oContext);
|
|
808
|
+
} else {
|
|
809
|
+
Log.warning("Cannot determine target type to request property value for bound action invocation");
|
|
810
|
+
return Promise.resolve(undefined);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
return oContext.requestObject(sProperty);
|
|
816
|
+
}
|
|
817
|
+
function _requestProperty(oSelectedContext: any, sAction: any, sProperty: any, sDynamicActionEnabledPath: any) {
|
|
818
|
+
const oPromise =
|
|
819
|
+
sProperty && sProperty.indexOf("/") === 0
|
|
820
|
+
? requestSingletonProperty(sProperty, oSelectedContext.getModel())
|
|
821
|
+
: _requestObject(sAction, oSelectedContext, sProperty);
|
|
822
|
+
|
|
823
|
+
return oPromise.then(function(vPropertyValue: any) {
|
|
824
|
+
return Promise.resolve({
|
|
825
|
+
vPropertyValue: vPropertyValue,
|
|
826
|
+
oSelectedContext: oSelectedContext,
|
|
827
|
+
sAction: sAction,
|
|
828
|
+
sDynamicActionEnabledPath: sDynamicActionEnabledPath
|
|
829
|
+
});
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
function _setContextsBasedOnOperationAvailable(oInternalModelContext: any, aRequestPromises: any) {
|
|
833
|
+
return Promise.all(aRequestPromises)
|
|
834
|
+
.then(function(aResults: [any, any, any, any, any, any, any, any, any, any]) {
|
|
835
|
+
if (aResults.length) {
|
|
836
|
+
const aApplicableContexts: any[] = [],
|
|
837
|
+
aNotApplicableContexts: any[] = [];
|
|
838
|
+
aResults.forEach(function(aResult: any) {
|
|
839
|
+
if (aResult) {
|
|
840
|
+
if (aResult.vPropertyValue) {
|
|
841
|
+
oInternalModelContext.getModel().setProperty(aResult.sDynamicActionEnabledPath, true);
|
|
842
|
+
aApplicableContexts.push(aResult.oSelectedContext);
|
|
843
|
+
} else {
|
|
844
|
+
aNotApplicableContexts.push(aResult.oSelectedContext);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
_setDynamicActionContexts(oInternalModelContext, aResults[0].sAction, aApplicableContexts, aNotApplicableContexts);
|
|
849
|
+
}
|
|
850
|
+
})
|
|
851
|
+
.catch(function(oError: any) {
|
|
852
|
+
Log.trace("Cannot retrieve property value from path", oError);
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
/**
|
|
856
|
+
* @param oInternalModelContext
|
|
857
|
+
* @param sAction
|
|
858
|
+
* @param aApplicable
|
|
859
|
+
* @param aNotApplicable
|
|
860
|
+
*/
|
|
861
|
+
function _setDynamicActionContexts(oInternalModelContext: any, sAction: any, aApplicable: any, aNotApplicable: any) {
|
|
862
|
+
const sDynamicActionPathPrefix = oInternalModelContext.getPath() + "/dynamicActions/" + sAction,
|
|
863
|
+
oInternalModel = oInternalModelContext.getModel();
|
|
864
|
+
oInternalModel.setProperty(sDynamicActionPathPrefix + "/aApplicable", aApplicable);
|
|
865
|
+
oInternalModel.setProperty(sDynamicActionPathPrefix + "/aNotApplicable", aNotApplicable);
|
|
866
|
+
}
|
|
867
|
+
function setActionEnablement(oInternalModelContext: any, oActionOperationAvailableMap: any, aSelectedContexts: any) {
|
|
868
|
+
const aPromises = [];
|
|
869
|
+
for (const sAction in oActionOperationAvailableMap) {
|
|
870
|
+
// Reset all properties before computation
|
|
871
|
+
oInternalModelContext.setProperty("dynamicActions/" + sAction, {
|
|
872
|
+
bEnabled: false,
|
|
873
|
+
aApplicable: [],
|
|
874
|
+
aNotApplicable: []
|
|
875
|
+
});
|
|
876
|
+
// Note that non dynamic actions are not processed here. They are enabled because
|
|
877
|
+
// one or more are selected and the second part of the condition in the templating
|
|
878
|
+
// is then undefined and thus the button takes the default enabling, which is true!
|
|
879
|
+
const aApplicable = [],
|
|
880
|
+
aNotApplicable = [],
|
|
881
|
+
sProperty = oActionOperationAvailableMap[sAction],
|
|
882
|
+
sDynamicActionEnabledPath = oInternalModelContext.getPath() + "/dynamicActions/" + sAction + "/bEnabled";
|
|
883
|
+
|
|
884
|
+
if (typeof sProperty === "object" && sProperty !== null && sProperty !== undefined) {
|
|
885
|
+
for (let i = 0; i < aSelectedContexts.length; i++) {
|
|
886
|
+
const oSelectedContext = aSelectedContexts[i];
|
|
887
|
+
if (oSelectedContext) {
|
|
888
|
+
const oContextData = oSelectedContext.getObject();
|
|
889
|
+
const oTransformedBinding = transformRecursively(
|
|
890
|
+
sProperty,
|
|
891
|
+
"Binding",
|
|
892
|
+
// eslint-disable-next-line no-loop-func
|
|
893
|
+
function(oBindingExpression: any) {
|
|
894
|
+
return constant(oContextData[oBindingExpression.path]);
|
|
895
|
+
},
|
|
896
|
+
true
|
|
897
|
+
);
|
|
898
|
+
const sResult = compileBinding(oTransformedBinding);
|
|
899
|
+
if (sResult === "true") {
|
|
900
|
+
oInternalModelContext.getModel().setProperty(sDynamicActionEnabledPath, true);
|
|
901
|
+
aApplicable.push(oSelectedContext);
|
|
902
|
+
} else {
|
|
903
|
+
aNotApplicable.push(oSelectedContext);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
_setDynamicActionContexts(oInternalModelContext, sAction, aApplicable, aNotApplicable);
|
|
908
|
+
} else {
|
|
909
|
+
const aRequestPromises = [];
|
|
910
|
+
for (let i = 0; i < aSelectedContexts.length; i++) {
|
|
911
|
+
const oSelectedContext = aSelectedContexts[i];
|
|
912
|
+
if (oSelectedContext) {
|
|
913
|
+
const oContextData = oSelectedContext.getObject();
|
|
914
|
+
if (sProperty === null && !!oContextData["#" + sAction]) {
|
|
915
|
+
//look for action advertisement if present and its value is not null
|
|
916
|
+
oInternalModelContext.getModel().setProperty(sDynamicActionEnabledPath, true);
|
|
917
|
+
break;
|
|
918
|
+
} else {
|
|
919
|
+
// Collect promises to retrieve singleton or normal property value asynchronously
|
|
920
|
+
aRequestPromises.push(_requestProperty(oSelectedContext, sAction, sProperty, sDynamicActionEnabledPath));
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// When all property values have been retrieved, set
|
|
926
|
+
// The applicable and not-applicable selected contexts for each action and
|
|
927
|
+
// The enabled property of the dynamic action in internal model context.
|
|
928
|
+
aPromises.push(_setContextsBasedOnOperationAvailable(oInternalModelContext, aRequestPromises));
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
return Promise.all(aPromises);
|
|
932
|
+
}
|
|
933
|
+
function _getDefaultOperators(oRealProperty: any) {
|
|
934
|
+
// mdc defines the full set of operations that are meaningful for each Edm Type
|
|
935
|
+
const oDataClass = TypeUtil.getDataTypeClassName(oRealProperty);
|
|
936
|
+
const oBaseType = TypeUtil.getBaseType(oDataClass);
|
|
937
|
+
return FilterOperatorUtil.getOperatorsForType(oBaseType);
|
|
938
|
+
}
|
|
939
|
+
function _getRestrictions(aDefaultOps: any, aExpressionOps: any) {
|
|
940
|
+
// From the default set of Operators for the Base Type, select those that are defined in the Allowed Value.
|
|
941
|
+
// In case that no operators are found, return undefined so that the default set is used.
|
|
942
|
+
const aOperators = aDefaultOps.filter(function(sElement: any) {
|
|
943
|
+
return aExpressionOps.indexOf(sElement) > -1;
|
|
944
|
+
});
|
|
945
|
+
return aOperators.toString() || undefined;
|
|
946
|
+
}
|
|
947
|
+
function getSpecificAllowedExpression(aExpressions: any) {
|
|
948
|
+
const aAllowedExpressionsPriority = CommonUtils.AllowedExpressionsPrio;
|
|
949
|
+
|
|
950
|
+
aExpressions.sort(function(a: any, b: any) {
|
|
951
|
+
return aAllowedExpressionsPriority.indexOf(a) - aAllowedExpressionsPriority.indexOf(b);
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
return aExpressions[0];
|
|
955
|
+
}
|
|
956
|
+
function getOperatorsForProperty(
|
|
957
|
+
sProperty: any,
|
|
958
|
+
sEntitySetPath: any,
|
|
959
|
+
oContext: any,
|
|
960
|
+
sType?: any,
|
|
961
|
+
bUseSemanticDateRange?: any,
|
|
962
|
+
sSettings?: any
|
|
963
|
+
) {
|
|
964
|
+
const oFilterRestrictions = CommonUtils.getFilterRestrictionsByPath(sEntitySetPath, oContext);
|
|
965
|
+
const aEqualsOps = ["EQ"];
|
|
966
|
+
const aSingleRangeOps = ["EQ", "GE", "LE", "LT", "GT", "BT", "NOTLE", "NOTLT", "NOTGE", "NOTGT"];
|
|
967
|
+
const aSingleValueDateOps = ["TODAY", "TOMORROW", "YESTERDAY", "DATE"];
|
|
968
|
+
const aMultiRangeOps = ["EQ", "GE", "LE", "LT", "GT", "BT", "NE", "NOTBT", "NOTLE", "NOTLT", "NOTGE", "NOTGT"];
|
|
969
|
+
const aSearchExpressionOps = ["Contains", "NotContains", "StartsWith", "NotStartsWith", "EndsWith", "NotEndsWith"];
|
|
970
|
+
const aSemanticDateOpsExt = SemanticDateOperators.getSupportedOperations();
|
|
971
|
+
const bSemanticDateRange = bUseSemanticDateRange === "true" || bUseSemanticDateRange === true;
|
|
972
|
+
let aSemanticDateOps: any[] = [];
|
|
973
|
+
const oSettings = typeof sSettings === "string" ? JSON.parse(sSettings).customData : sSettings;
|
|
974
|
+
|
|
975
|
+
if (oContext.getObject(sEntitySetPath + "/@com.sap.vocabularies.Common.v1.ResultContext") === true) {
|
|
976
|
+
return aEqualsOps.toString();
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
if (oSettings && oSettings.operatorConfiguration && oSettings.operatorConfiguration.length > 0) {
|
|
980
|
+
aSemanticDateOps = SemanticDateOperators.getFilterOperations(oSettings.operatorConfiguration);
|
|
981
|
+
} else {
|
|
982
|
+
aSemanticDateOps = SemanticDateOperators.getSemanticDateOperations();
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// Get the default Operators for this Property Type
|
|
986
|
+
let aDefaultOperators = _getDefaultOperators(sType);
|
|
987
|
+
|
|
988
|
+
// Is there a Filter Restriction defined for this property?
|
|
989
|
+
if (oFilterRestrictions && oFilterRestrictions.FilterAllowedExpressions && oFilterRestrictions.FilterAllowedExpressions[sProperty]) {
|
|
990
|
+
// Extending the default operators list with Semantic Date options DATERANGE, DATE, FROM and TO
|
|
991
|
+
if (bSemanticDateRange) {
|
|
992
|
+
aDefaultOperators = aSemanticDateOpsExt.concat(aDefaultOperators);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
const sAllowedExpression = CommonUtils.getSpecificAllowedExpression(oFilterRestrictions.FilterAllowedExpressions[sProperty]);
|
|
996
|
+
let sRestrictions;
|
|
997
|
+
// In case more than one Allowed Expressions has been defined for a property
|
|
998
|
+
// choose the most restrictive Allowed Expression
|
|
999
|
+
|
|
1000
|
+
// MultiValue has same Operator as SingleValue, but there can be more than one (maxConditions)
|
|
1001
|
+
switch (sAllowedExpression) {
|
|
1002
|
+
case "SingleValue":
|
|
1003
|
+
const aSingleValueOps = sType === "Edm.Date" && bSemanticDateRange ? aSingleValueDateOps : aEqualsOps;
|
|
1004
|
+
sRestrictions = _getRestrictions(aDefaultOperators, aSingleValueOps);
|
|
1005
|
+
break;
|
|
1006
|
+
case "MultiValue":
|
|
1007
|
+
sRestrictions = _getRestrictions(aDefaultOperators, aEqualsOps);
|
|
1008
|
+
break;
|
|
1009
|
+
case "SingleRange":
|
|
1010
|
+
const sOperators = _getRestrictions(
|
|
1011
|
+
aDefaultOperators,
|
|
1012
|
+
sType === "Edm.Date" && bSemanticDateRange ? aSemanticDateOps : aSingleRangeOps
|
|
1013
|
+
);
|
|
1014
|
+
sRestrictions = sOperators ? sOperators : "";
|
|
1015
|
+
break;
|
|
1016
|
+
case "MultiRange":
|
|
1017
|
+
sRestrictions = _getRestrictions(aDefaultOperators, aMultiRangeOps);
|
|
1018
|
+
break;
|
|
1019
|
+
case "SearchExpression":
|
|
1020
|
+
sRestrictions = _getRestrictions(aDefaultOperators, aSearchExpressionOps);
|
|
1021
|
+
break;
|
|
1022
|
+
case "MultiRangeOrSearchExpression":
|
|
1023
|
+
sRestrictions = _getRestrictions(aDefaultOperators, aSearchExpressionOps.concat(aMultiRangeOps));
|
|
1024
|
+
break;
|
|
1025
|
+
|
|
1026
|
+
default:
|
|
1027
|
+
break;
|
|
1028
|
+
}
|
|
1029
|
+
// In case AllowedExpressions is not recognised, undefined in return results in the default set of
|
|
1030
|
+
// operators for the type.
|
|
1031
|
+
return sRestrictions;
|
|
1032
|
+
} else if (sType === "Edm.Date") {
|
|
1033
|
+
// In case AllowedExpressions is not provided for type Edm.Date then all the default
|
|
1034
|
+
// operators for the type should be returned excluding semantic operators from the list.
|
|
1035
|
+
aSemanticDateOps = SemanticDateOperators.getSemanticDateOperations();
|
|
1036
|
+
const aOperators = aDefaultOperators.filter(function(sElement: any) {
|
|
1037
|
+
return aSemanticDateOps.indexOf(sElement) < 0;
|
|
1038
|
+
});
|
|
1039
|
+
return aOperators.toString();
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
function getParameterInfo(oMetaModel: any, sContextPath: any) {
|
|
1043
|
+
const sParameterContextPath = sContextPath.substring(0, sContextPath.lastIndexOf("/"));
|
|
1044
|
+
const bResultContext = oMetaModel.getObject(sParameterContextPath + "/@com.sap.vocabularies.Common.v1.ResultContext");
|
|
1045
|
+
const oParameterInfo: any = {};
|
|
1046
|
+
if (bResultContext && sParameterContextPath !== sContextPath) {
|
|
1047
|
+
oParameterInfo.contextPath = sParameterContextPath;
|
|
1048
|
+
oParameterInfo.parameterProperties = CommonUtils.getContextPathProperties(oMetaModel, sParameterContextPath);
|
|
1049
|
+
}
|
|
1050
|
+
return oParameterInfo;
|
|
1051
|
+
}
|
|
1052
|
+
function addSelectOptionToConditions(oPropertyMetadata: any, aValidOperators: any, aCumulativeConditions: any, oSelectOption: any) {
|
|
1053
|
+
const oCondition = getConditions(oSelectOption, oPropertyMetadata);
|
|
1054
|
+
if (oCondition) {
|
|
1055
|
+
if (!aValidOperators || aValidOperators.indexOf(oCondition.operator) > -1) {
|
|
1056
|
+
aCumulativeConditions.push(oCondition);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
return aCumulativeConditions;
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* @param sContextPath
|
|
1063
|
+
* @param oSelectionVariant
|
|
1064
|
+
* @param sSelectOptionProp
|
|
1065
|
+
* @param oConditions
|
|
1066
|
+
* @param sConditionPath
|
|
1067
|
+
* @param sConditionProp
|
|
1068
|
+
* @param oValidProperties
|
|
1069
|
+
* @param oMetaModel
|
|
1070
|
+
* @param isParameter
|
|
1071
|
+
*/
|
|
1072
|
+
function addSelectOptionsToConditions(
|
|
1073
|
+
sContextPath: any,
|
|
1074
|
+
oSelectionVariant: any,
|
|
1075
|
+
sSelectOptionProp: any,
|
|
1076
|
+
oConditions: any,
|
|
1077
|
+
sConditionPath: any,
|
|
1078
|
+
sConditionProp: any,
|
|
1079
|
+
oValidProperties: any,
|
|
1080
|
+
oMetaModel: any,
|
|
1081
|
+
isParameter: any
|
|
1082
|
+
) {
|
|
1083
|
+
let aConditions: any[] = [],
|
|
1084
|
+
aSelectOptions,
|
|
1085
|
+
aValidOperators;
|
|
1086
|
+
|
|
1087
|
+
if (isParameter || CommonUtils.isPropertyFilterable(oMetaModel, sContextPath, sConditionProp, true)) {
|
|
1088
|
+
aSelectOptions = oSelectionVariant.getSelectOption(sSelectOptionProp);
|
|
1089
|
+
aValidOperators = isParameter ? ["EQ"] : CommonUtils.getOperatorsForProperty(sConditionProp, sContextPath, oMetaModel);
|
|
1090
|
+
const oPropertyMetadata = oValidProperties[sConditionProp];
|
|
1091
|
+
// Create conditions for all the selectOptions of the property
|
|
1092
|
+
aConditions = isParameter
|
|
1093
|
+
? addSelectOptionToConditions(oPropertyMetadata, aValidOperators, aConditions, aSelectOptions[0])
|
|
1094
|
+
: aSelectOptions.reduce(addSelectOptionToConditions.bind(null, oPropertyMetadata, aValidOperators), aConditions);
|
|
1095
|
+
if (aConditions.length) {
|
|
1096
|
+
if (sConditionPath) {
|
|
1097
|
+
oConditions[sConditionPath + sConditionProp] = oConditions.hasOwnProperty(sConditionPath + sConditionProp)
|
|
1098
|
+
? oConditions[sConditionPath + sConditionProp].concat(aConditions)
|
|
1099
|
+
: aConditions;
|
|
1100
|
+
} else {
|
|
1101
|
+
oConditions[sConditionProp] = oConditions.hasOwnProperty(sConditionProp)
|
|
1102
|
+
? oConditions[sConditionProp].concat(aConditions)
|
|
1103
|
+
: aConditions;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
function addSelectionVariantToConditions(oSelectionVariant: any, oConditions: object, oMetaModel: ODataMetaModel, sContextPath: string) {
|
|
1110
|
+
const aSelectOptionsPropertyNames = oSelectionVariant.getSelectOptionsPropertyNames(),
|
|
1111
|
+
oValidProperties = CommonUtils.getContextPathProperties(oMetaModel, sContextPath),
|
|
1112
|
+
aMetadatProperties = Object.keys(oValidProperties),
|
|
1113
|
+
oParameterInfo = CommonUtils.getParameterInfo(oMetaModel, sContextPath),
|
|
1114
|
+
sParameterContextPath = oParameterInfo.contextPath,
|
|
1115
|
+
oValidParameterProperties = oParameterInfo.parameterProperties,
|
|
1116
|
+
bHasParameters = !!oParameterInfo.contextPath && oValidParameterProperties && Object.keys(oValidParameterProperties).length > 0;
|
|
1117
|
+
|
|
1118
|
+
if (bHasParameters) {
|
|
1119
|
+
const aMetadataParameters = Object.keys(oValidParameterProperties);
|
|
1120
|
+
aMetadataParameters.forEach(function(sMetadataParameter: string) {
|
|
1121
|
+
let sSelectOptionName;
|
|
1122
|
+
if (aSelectOptionsPropertyNames.includes("$Parameter." + sMetadataParameter)) {
|
|
1123
|
+
sSelectOptionName = "$Parameter." + sMetadataParameter;
|
|
1124
|
+
} else if (aSelectOptionsPropertyNames.includes(sMetadataParameter)) {
|
|
1125
|
+
sSelectOptionName = sMetadataParameter;
|
|
1126
|
+
} else if (
|
|
1127
|
+
sMetadataParameter.startsWith("P_") &&
|
|
1128
|
+
aSelectOptionsPropertyNames.includes("$Parameter." + sMetadataParameter.slice(2, sMetadataParameter.length))
|
|
1129
|
+
) {
|
|
1130
|
+
sSelectOptionName = "$Parameter." + sMetadataParameter.slice(2, sMetadataParameter.length);
|
|
1131
|
+
} else if (
|
|
1132
|
+
sMetadataParameter.startsWith("P_") &&
|
|
1133
|
+
aSelectOptionsPropertyNames.includes(sMetadataParameter.slice(2, sMetadataParameter.length))
|
|
1134
|
+
) {
|
|
1135
|
+
sSelectOptionName = sMetadataParameter.slice(2, sMetadataParameter.length);
|
|
1136
|
+
} else if (aSelectOptionsPropertyNames.includes("$Parameter.P_" + sMetadataParameter)) {
|
|
1137
|
+
sSelectOptionName = "$Parameter.P_" + sMetadataParameter;
|
|
1138
|
+
} else if (aSelectOptionsPropertyNames.includes("P_" + sMetadataParameter)) {
|
|
1139
|
+
sSelectOptionName = "P_" + sMetadataParameter;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
if (sSelectOptionName) {
|
|
1143
|
+
addSelectOptionsToConditions(
|
|
1144
|
+
sParameterContextPath,
|
|
1145
|
+
oSelectionVariant,
|
|
1146
|
+
sSelectOptionName,
|
|
1147
|
+
oConditions,
|
|
1148
|
+
undefined,
|
|
1149
|
+
sMetadataParameter,
|
|
1150
|
+
oValidParameterProperties,
|
|
1151
|
+
oMetaModel,
|
|
1152
|
+
true
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
aMetadatProperties.forEach(function(sMetadataProperty: string) {
|
|
1158
|
+
let sSelectOptionName;
|
|
1159
|
+
if (aSelectOptionsPropertyNames.includes(sMetadataProperty)) {
|
|
1160
|
+
sSelectOptionName = sMetadataProperty;
|
|
1161
|
+
} else if (
|
|
1162
|
+
sMetadataProperty.startsWith("P_") &&
|
|
1163
|
+
aSelectOptionsPropertyNames.includes(sMetadataProperty.slice(2, sMetadataProperty.length))
|
|
1164
|
+
) {
|
|
1165
|
+
sSelectOptionName = sMetadataProperty.slice(2, sMetadataProperty.length);
|
|
1166
|
+
} else if (aSelectOptionsPropertyNames.includes("P_" + sMetadataProperty)) {
|
|
1167
|
+
sSelectOptionName = "P_" + sMetadataProperty;
|
|
1168
|
+
}
|
|
1169
|
+
if (sSelectOptionName) {
|
|
1170
|
+
addSelectOptionsToConditions(
|
|
1171
|
+
sContextPath,
|
|
1172
|
+
oSelectionVariant,
|
|
1173
|
+
sSelectOptionName,
|
|
1174
|
+
oConditions,
|
|
1175
|
+
undefined,
|
|
1176
|
+
sMetadataProperty,
|
|
1177
|
+
oValidProperties,
|
|
1178
|
+
oMetaModel,
|
|
1179
|
+
false
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
});
|
|
1183
|
+
|
|
1184
|
+
aSelectOptionsPropertyNames.forEach(function(sSelectOption: any) {
|
|
1185
|
+
if (sSelectOption.indexOf(".") > 0 && !sSelectOption.includes("$Parameter")) {
|
|
1186
|
+
const sFullContextPath = ("/" + sSelectOption.replaceAll(".", "/")).startsWith(sContextPath)
|
|
1187
|
+
? "/" + sSelectOption.replaceAll(".", "/")
|
|
1188
|
+
: sContextPath + "/" + sSelectOption.replaceAll(".", "/"); // check if the full path, eg SalesOrderManage._Item.Material exists in the metamodel
|
|
1189
|
+
if (oMetaModel.getObject(sFullContextPath.replace("P_", ""))) {
|
|
1190
|
+
_createConditionsForNavProperties(
|
|
1191
|
+
sFullContextPath,
|
|
1192
|
+
sContextPath,
|
|
1193
|
+
oSelectionVariant,
|
|
1194
|
+
sSelectOption,
|
|
1195
|
+
oMetaModel,
|
|
1196
|
+
oConditions
|
|
1197
|
+
);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
});
|
|
1201
|
+
return oConditions;
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* @param sFullContextPath
|
|
1205
|
+
* @param sMainEntitySetPath
|
|
1206
|
+
* @param oSelectionVariant
|
|
1207
|
+
* @param sSelectOption
|
|
1208
|
+
* @param oMetaModel
|
|
1209
|
+
* @param oConditions
|
|
1210
|
+
*/
|
|
1211
|
+
function _createConditionsForNavProperties(
|
|
1212
|
+
sFullContextPath: any,
|
|
1213
|
+
sMainEntitySetPath: any,
|
|
1214
|
+
oSelectionVariant: any,
|
|
1215
|
+
sSelectOption: any,
|
|
1216
|
+
oMetaModel: any,
|
|
1217
|
+
oConditions: any
|
|
1218
|
+
) {
|
|
1219
|
+
let aNavObjectNames = sSelectOption.split(".");
|
|
1220
|
+
// Eg: "SalesOrderManage._Item._Material.Material" or "_Item.Material"
|
|
1221
|
+
if (("/" + sSelectOption.replaceAll(".", "/")).startsWith(sMainEntitySetPath)) {
|
|
1222
|
+
const sFullPath = (("/" + sSelectOption) as any).replaceAll(".", "/"),
|
|
1223
|
+
sNavPath = sFullPath.replace(sMainEntitySetPath + "/", "");
|
|
1224
|
+
aNavObjectNames = sNavPath.split("/");
|
|
1225
|
+
}
|
|
1226
|
+
let sConditionPath = "";
|
|
1227
|
+
const sPropertyName = aNavObjectNames[aNavObjectNames.length - 1]; // Material from SalesOrderManage._Item.Material
|
|
1228
|
+
for (let i = 0; i < aNavObjectNames.length - 1; i++) {
|
|
1229
|
+
if (oMetaModel.getObject(sMainEntitySetPath + "/" + aNavObjectNames[i].replace("P_", "")).$isCollection) {
|
|
1230
|
+
sConditionPath = sConditionPath + aNavObjectNames[i] + "*/"; // _Item*/ in case of 1:n cardinality
|
|
1231
|
+
} else {
|
|
1232
|
+
sConditionPath = sConditionPath + aNavObjectNames[i] + "/"; // _Item/ in case of 1:1 cardinality
|
|
1233
|
+
}
|
|
1234
|
+
sMainEntitySetPath = sMainEntitySetPath + "/" + aNavObjectNames[i];
|
|
1235
|
+
}
|
|
1236
|
+
const sNavPropertyPath = sFullContextPath.slice(0, sFullContextPath.lastIndexOf("/")),
|
|
1237
|
+
oValidProperties = CommonUtils.getContextPathProperties(oMetaModel, sNavPropertyPath),
|
|
1238
|
+
aSelectOptionsPropertyNames = oSelectionVariant.getSelectOptionsPropertyNames();
|
|
1239
|
+
let sSelectOptionName = sPropertyName;
|
|
1240
|
+
if (oValidProperties[sPropertyName]) {
|
|
1241
|
+
sSelectOptionName = sPropertyName;
|
|
1242
|
+
} else if (sPropertyName.startsWith("P_") && oValidProperties[sPropertyName.replace("P_", "")]) {
|
|
1243
|
+
sSelectOptionName = sPropertyName.replace("P_", "");
|
|
1244
|
+
} else if (oValidProperties["P_" + sPropertyName] && aSelectOptionsPropertyNames.includes("P_" + sPropertyName)) {
|
|
1245
|
+
sSelectOptionName = "P_" + sPropertyName;
|
|
1246
|
+
}
|
|
1247
|
+
if (sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
|
|
1248
|
+
// if there is no SalesOrderManage._Item.Material yet in the oConditions
|
|
1249
|
+
return;
|
|
1250
|
+
} else if (!sPropertyName.startsWith("P_") && oConditions[sConditionPath + sSelectOptionName]) {
|
|
1251
|
+
delete oConditions[sConditionPath + sSelectOptionName];
|
|
1252
|
+
addSelectOptionsToConditions(
|
|
1253
|
+
sNavPropertyPath,
|
|
1254
|
+
oSelectionVariant,
|
|
1255
|
+
sSelectOption,
|
|
1256
|
+
oConditions,
|
|
1257
|
+
sConditionPath,
|
|
1258
|
+
sSelectOptionName,
|
|
1259
|
+
oValidProperties,
|
|
1260
|
+
oMetaModel,
|
|
1261
|
+
false
|
|
1262
|
+
);
|
|
1263
|
+
} else {
|
|
1264
|
+
addSelectOptionsToConditions(
|
|
1265
|
+
sNavPropertyPath,
|
|
1266
|
+
oSelectionVariant,
|
|
1267
|
+
sSelectOption,
|
|
1268
|
+
oConditions,
|
|
1269
|
+
sConditionPath,
|
|
1270
|
+
sSelectOptionName,
|
|
1271
|
+
oValidProperties,
|
|
1272
|
+
oMetaModel,
|
|
1273
|
+
false
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
function addPageContextToSelectionVariant(oSelectionVariant: any, mPageContext: any[], oView: any) {
|
|
1278
|
+
const oAppComponent = CommonUtils.getAppComponent(oView);
|
|
1279
|
+
const oNavigationService = oAppComponent.getNavigationService();
|
|
1280
|
+
return oNavigationService.mixAttributesAndSelectionVariant(mPageContext, oSelectionVariant.toJSONString());
|
|
1281
|
+
}
|
|
1282
|
+
function addExternalStateFiltersToSelectionVariant(oSelectionVariant: any, mFilters: any, oTargetInfo: any, oFilterInfo: any) {
|
|
1283
|
+
let sFilter: any,
|
|
1284
|
+
sLow = "",
|
|
1285
|
+
sHigh = null;
|
|
1286
|
+
const fnGetSignAndOption = function(sOperator: any, sLowValue: any, sHighValue: any) {
|
|
1287
|
+
const oSelectOptionState = {
|
|
1288
|
+
option: "",
|
|
1289
|
+
sign: "I",
|
|
1290
|
+
low: sLowValue,
|
|
1291
|
+
high: sHighValue
|
|
1292
|
+
};
|
|
1293
|
+
switch (sOperator) {
|
|
1294
|
+
case "Contains":
|
|
1295
|
+
oSelectOptionState.option = "CP";
|
|
1296
|
+
break;
|
|
1297
|
+
case "StartsWith":
|
|
1298
|
+
oSelectOptionState.option = "CP";
|
|
1299
|
+
oSelectOptionState.low += "*";
|
|
1300
|
+
break;
|
|
1301
|
+
case "EndsWith":
|
|
1302
|
+
oSelectOptionState.option = "CP";
|
|
1303
|
+
oSelectOptionState.low = "*" + oSelectOptionState.low;
|
|
1304
|
+
break;
|
|
1305
|
+
case "BT":
|
|
1306
|
+
case "LE":
|
|
1307
|
+
case "LT":
|
|
1308
|
+
case "GT":
|
|
1309
|
+
case "NE":
|
|
1310
|
+
case "EQ":
|
|
1311
|
+
oSelectOptionState.option = sOperator;
|
|
1312
|
+
break;
|
|
1313
|
+
case "TODAY":
|
|
1314
|
+
case "DATE":
|
|
1315
|
+
oSelectOptionState.option = "EQ";
|
|
1316
|
+
break;
|
|
1317
|
+
case "EEQ":
|
|
1318
|
+
oSelectOptionState.option = "EQ";
|
|
1319
|
+
break;
|
|
1320
|
+
case "Empty":
|
|
1321
|
+
oSelectOptionState.option = "EQ";
|
|
1322
|
+
oSelectOptionState.low = "";
|
|
1323
|
+
break;
|
|
1324
|
+
case "NotContains":
|
|
1325
|
+
oSelectOptionState.option = "CP";
|
|
1326
|
+
oSelectOptionState.sign = "E";
|
|
1327
|
+
break;
|
|
1328
|
+
case "NOTBT":
|
|
1329
|
+
oSelectOptionState.option = "BT";
|
|
1330
|
+
oSelectOptionState.sign = "E";
|
|
1331
|
+
break;
|
|
1332
|
+
case "NotStartsWith":
|
|
1333
|
+
oSelectOptionState.option = "CP";
|
|
1334
|
+
oSelectOptionState.low += "*";
|
|
1335
|
+
oSelectOptionState.sign = "E";
|
|
1336
|
+
break;
|
|
1337
|
+
case "NotEndsWith":
|
|
1338
|
+
oSelectOptionState.option = "CP";
|
|
1339
|
+
oSelectOptionState.low = "*" + oSelectOptionState.low;
|
|
1340
|
+
oSelectOptionState.sign = "E";
|
|
1341
|
+
break;
|
|
1342
|
+
case "NotEmpty":
|
|
1343
|
+
oSelectOptionState.option = "NE";
|
|
1344
|
+
oSelectOptionState.low = "";
|
|
1345
|
+
break;
|
|
1346
|
+
case "NOTLE":
|
|
1347
|
+
oSelectOptionState.option = "LE";
|
|
1348
|
+
oSelectOptionState.sign = "E";
|
|
1349
|
+
break;
|
|
1350
|
+
case "NOTGE":
|
|
1351
|
+
oSelectOptionState.option = "GE";
|
|
1352
|
+
oSelectOptionState.sign = "E";
|
|
1353
|
+
break;
|
|
1354
|
+
case "NOTLT":
|
|
1355
|
+
oSelectOptionState.option = "LT";
|
|
1356
|
+
oSelectOptionState.sign = "E";
|
|
1357
|
+
break;
|
|
1358
|
+
case "NOTGT":
|
|
1359
|
+
oSelectOptionState.option = "GT";
|
|
1360
|
+
oSelectOptionState.sign = "E";
|
|
1361
|
+
break;
|
|
1362
|
+
default:
|
|
1363
|
+
Log.warning(sOperator + " is not supported. " + sFilter + " could not be added to the navigation context");
|
|
1364
|
+
}
|
|
1365
|
+
return oSelectOptionState;
|
|
1366
|
+
};
|
|
1367
|
+
const oFilterConditions = mFilters.filterConditions;
|
|
1368
|
+
const oFiltersWithoutConflict = mFilters.filterConditionsWithoutConflict ? mFilters.filterConditionsWithoutConflict : {};
|
|
1369
|
+
const oTablePropertiesWithoutConflict = oTargetInfo.propertiesWithoutConflict ? oTargetInfo.propertiesWithoutConflict : {};
|
|
1370
|
+
const addFiltersToSelectionVariant = function(oSelectionVariant: any, sFilterName: any, sPath?: any) {
|
|
1371
|
+
const aFilters = oFilterConditions[sFilterName];
|
|
1372
|
+
for (const item in aFilters) {
|
|
1373
|
+
const oFilter = aFilters[item];
|
|
1374
|
+
sLow = (oFilter.values[0] && oFilter.values[0].toString()) || "";
|
|
1375
|
+
sHigh = (oFilter.values[1] && oFilter.values[1].toString()) || null;
|
|
1376
|
+
if (oFilter.operator === "TODAY" || oFilter.operator === "DATE") {
|
|
1377
|
+
const aFilter = oFilterInfo[0].aFilters.filter(function(oFilter: any) {
|
|
1378
|
+
return oFilter.sPath === sFilterName;
|
|
1379
|
+
});
|
|
1380
|
+
sLow = aFilter[0].oValue1 || "";
|
|
1381
|
+
sHigh = null;
|
|
1382
|
+
}
|
|
1383
|
+
const oSelectOptionValues = fnGetSignAndOption(oFilter.operator, sLow, sHigh);
|
|
1384
|
+
if (oSelectOptionValues.option) {
|
|
1385
|
+
oSelectionVariant.addSelectOption(
|
|
1386
|
+
sPath ? sPath : sFilterName,
|
|
1387
|
+
oSelectOptionValues.sign,
|
|
1388
|
+
oSelectOptionValues.option,
|
|
1389
|
+
oSelectOptionValues.low,
|
|
1390
|
+
oSelectOptionValues.high
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
};
|
|
1395
|
+
|
|
1396
|
+
for (sFilter in oFilterConditions) {
|
|
1397
|
+
// only add the filter values if it is not already present in the SV already
|
|
1398
|
+
if (!oSelectionVariant.getSelectOption(sFilter)) {
|
|
1399
|
+
// TODO : custom filters should be ignored more generically
|
|
1400
|
+
if (sFilter === "$editState") {
|
|
1401
|
+
continue;
|
|
1402
|
+
}
|
|
1403
|
+
addFiltersToSelectionVariant(oSelectionVariant, sFilter);
|
|
1404
|
+
} else {
|
|
1405
|
+
if (oTablePropertiesWithoutConflict && sFilter in oTablePropertiesWithoutConflict) {
|
|
1406
|
+
addFiltersToSelectionVariant(oSelectionVariant, sFilter, oTablePropertiesWithoutConflict[sFilter]);
|
|
1407
|
+
}
|
|
1408
|
+
// if property was without conflict in page context then add path from page context to SV
|
|
1409
|
+
if (sFilter in oFiltersWithoutConflict) {
|
|
1410
|
+
addFiltersToSelectionVariant(oSelectionVariant, sFilter, oFiltersWithoutConflict[sFilter]);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
return oSelectionVariant;
|
|
1415
|
+
}
|
|
1416
|
+
function isStickyEditMode(oControl: Control) {
|
|
1417
|
+
const bIsStickyMode = ModelHelper.isStickySessionSupported((oControl.getModel() as ODataModel).getMetaModel());
|
|
1418
|
+
const bUIEditable = oControl.getModel("ui").getProperty("/isEditable");
|
|
1419
|
+
return bIsStickyMode && bUIEditable;
|
|
1420
|
+
}
|
|
1421
|
+
/**
|
|
1422
|
+
* @param aMandatoryFilterFields
|
|
1423
|
+
* @param oSelectionVariant
|
|
1424
|
+
* @param oSelectionVariantDefaults
|
|
1425
|
+
*/
|
|
1426
|
+
function addDefaultDisplayCurrency(aMandatoryFilterFields: any[], oSelectionVariant: any, oSelectionVariantDefaults: any) {
|
|
1427
|
+
if (oSelectionVariant && aMandatoryFilterFields && aMandatoryFilterFields.length) {
|
|
1428
|
+
for (let i = 0; i < aMandatoryFilterFields.length; i++) {
|
|
1429
|
+
const aSVOption = oSelectionVariant.getSelectOption("DisplayCurrency"),
|
|
1430
|
+
aDefaultSVOption = oSelectionVariantDefaults && oSelectionVariantDefaults.getSelectOption("DisplayCurrency");
|
|
1431
|
+
if (
|
|
1432
|
+
aMandatoryFilterFields[i].$PropertyPath === "DisplayCurrency" &&
|
|
1433
|
+
(!aSVOption || !aSVOption.length) &&
|
|
1434
|
+
aDefaultSVOption &&
|
|
1435
|
+
aDefaultSVOption.length
|
|
1436
|
+
) {
|
|
1437
|
+
const displayCurrencySelectOption = aDefaultSVOption[0];
|
|
1438
|
+
const sSign = displayCurrencySelectOption["Sign"];
|
|
1439
|
+
const sOption = displayCurrencySelectOption["Option"];
|
|
1440
|
+
const sLow = displayCurrencySelectOption["Low"];
|
|
1441
|
+
const sHigh = displayCurrencySelectOption["High"];
|
|
1442
|
+
oSelectionVariant.addSelectOption("DisplayCurrency", sSign, sOption, sLow, sHigh);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
function getNonComputedVisibleFields(oMetaModel: ODataMetaModel, sPath: any, oView: any) {
|
|
1448
|
+
const aTechnicalKeys = oMetaModel.getObject(sPath + "/").$Key;
|
|
1449
|
+
const aNonComputedVisibleFields = [];
|
|
1450
|
+
const oEntityType = oMetaModel.getObject(sPath + "/");
|
|
1451
|
+
for (const item in oEntityType) {
|
|
1452
|
+
if (oEntityType[item].$kind && oEntityType[item].$kind === "Property") {
|
|
1453
|
+
const oAnnotations = oMetaModel.getObject(sPath + "/" + item + "@") || {},
|
|
1454
|
+
bIsKey = aTechnicalKeys.indexOf(item) > -1,
|
|
1455
|
+
bIsImmutable = oAnnotations["@Org.OData.Core.V1.Immutable"],
|
|
1456
|
+
bIsNonComputed = !oAnnotations["@Org.OData.Core.V1.Computed"],
|
|
1457
|
+
bIsVisible = !oAnnotations["@com.sap.vocabularies.UI.v1.Hidden"],
|
|
1458
|
+
bIsComputedDefaultValue = oAnnotations["@Org.OData.Core.V1.ComputedDefaultValue"],
|
|
1459
|
+
bIsKeyComputedDefaultValueWithText =
|
|
1460
|
+
bIsKey && oEntityType[item].$Type === "Edm.Guid"
|
|
1461
|
+
? bIsComputedDefaultValue && oAnnotations["@com.sap.vocabularies.Common.v1.Text"]
|
|
1462
|
+
: false;
|
|
1463
|
+
if (
|
|
1464
|
+
(bIsImmutable || bIsKeyComputedDefaultValueWithText || (bIsKey && oEntityType[item].$Type !== "Edm.Guid")) &&
|
|
1465
|
+
bIsNonComputed &&
|
|
1466
|
+
bIsVisible
|
|
1467
|
+
) {
|
|
1468
|
+
aNonComputedVisibleFields.push(item);
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
if (!bIsNonComputed && bIsComputedDefaultValue && oView) {
|
|
1472
|
+
const oDiagnostics = getAppComponent(oView).getDiagnostics();
|
|
1473
|
+
const sMessage = "Core.ComputedDefaultValue is ignored as Core.Computed is already set to true";
|
|
1474
|
+
oDiagnostics.addIssue(
|
|
1475
|
+
IssueCategory.Annotation,
|
|
1476
|
+
IssueSeverity.Medium,
|
|
1477
|
+
sMessage,
|
|
1478
|
+
IssueCategoryType,
|
|
1479
|
+
IssueCategoryType?.Annotations?.IgnoredAnnotation
|
|
1480
|
+
);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
return aNonComputedVisibleFields;
|
|
1485
|
+
}
|
|
1486
|
+
function setUserDefaults(
|
|
1487
|
+
oAppComponent: AppComponent,
|
|
1488
|
+
aParameters: any[],
|
|
1489
|
+
oModel: JSONModel,
|
|
1490
|
+
bIsAction: boolean,
|
|
1491
|
+
bIsCreate?: boolean,
|
|
1492
|
+
oActionDefaultValues?: any
|
|
1493
|
+
) {
|
|
1494
|
+
return new Promise(function(resolve: (value: any) => void) {
|
|
1495
|
+
const oComponentData = oAppComponent.getComponentData(),
|
|
1496
|
+
oStartupParameters = (oComponentData && oComponentData.startupParameters) || {},
|
|
1497
|
+
oShellServices = oAppComponent.getShellServices();
|
|
1498
|
+
if (!oShellServices.hasUShell()) {
|
|
1499
|
+
aParameters.forEach(function(oParameter: any) {
|
|
1500
|
+
const sPropertyName = bIsAction
|
|
1501
|
+
? "/" + oParameter.$Name
|
|
1502
|
+
: oParameter.getPath().slice(oParameter.getPath().lastIndexOf("/") + 1);
|
|
1503
|
+
const sParameterName = bIsAction ? sPropertyName.slice(1) : sPropertyName;
|
|
1504
|
+
if (oActionDefaultValues && bIsCreate) {
|
|
1505
|
+
if (oActionDefaultValues[sParameterName]) {
|
|
1506
|
+
oModel.setProperty(sPropertyName, oActionDefaultValues[sParameterName]);
|
|
1507
|
+
}
|
|
1508
|
+
} else if (oStartupParameters[sParameterName]) {
|
|
1509
|
+
oModel.setProperty(sPropertyName, oStartupParameters[sParameterName][0]);
|
|
1510
|
+
}
|
|
1511
|
+
});
|
|
1512
|
+
return resolve(true);
|
|
1513
|
+
}
|
|
1514
|
+
return oShellServices.getStartupAppState(oAppComponent).then(function(oStartupAppState: any) {
|
|
1515
|
+
const oData = oStartupAppState.getData() || {},
|
|
1516
|
+
aExtendedParameters = (oData.selectionVariant && oData.selectionVariant.SelectOptions) || [];
|
|
1517
|
+
aParameters.forEach(function(oParameter: any) {
|
|
1518
|
+
const sPropertyName = bIsAction
|
|
1519
|
+
? "/" + oParameter.$Name
|
|
1520
|
+
: oParameter.getPath().slice(oParameter.getPath().lastIndexOf("/") + 1);
|
|
1521
|
+
const sParameterName = bIsAction ? sPropertyName.slice(1) : sPropertyName;
|
|
1522
|
+
if (oActionDefaultValues && bIsCreate) {
|
|
1523
|
+
if (oActionDefaultValues[sParameterName]) {
|
|
1524
|
+
oModel.setProperty(sPropertyName, oActionDefaultValues[sParameterName]);
|
|
1525
|
+
}
|
|
1526
|
+
} else if (oStartupParameters[sParameterName]) {
|
|
1527
|
+
oModel.setProperty(sPropertyName, oStartupParameters[sParameterName][0]);
|
|
1528
|
+
} else if (aExtendedParameters.length > 0) {
|
|
1529
|
+
for (const i in aExtendedParameters) {
|
|
1530
|
+
const oExtendedParameter = aExtendedParameters[i];
|
|
1531
|
+
if (oExtendedParameter.PropertyName === sParameterName) {
|
|
1532
|
+
const oRange = oExtendedParameter.Ranges.length ? oExtendedParameter.Ranges[0] : undefined;
|
|
1533
|
+
if (oRange && oRange.Sign === "I" && oRange.Option === "EQ") {
|
|
1534
|
+
oModel.setProperty(sPropertyName, oRange.Low); // high is ignored when Option=EQ
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
});
|
|
1540
|
+
return resolve(true);
|
|
1541
|
+
});
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
function getAdditionalParamsForCreate(oStartupParameters: any, oInboundParameters: any) {
|
|
1545
|
+
const oInbounds = oInboundParameters,
|
|
1546
|
+
aCreateParameters = oInbounds
|
|
1547
|
+
? Object.keys(oInbounds).filter(function(sParameter: string) {
|
|
1548
|
+
return oInbounds[sParameter].useForCreate;
|
|
1549
|
+
})
|
|
1550
|
+
: [];
|
|
1551
|
+
let oRet;
|
|
1552
|
+
for (let i = 0; i < aCreateParameters.length; i++) {
|
|
1553
|
+
const sCreateParameter = aCreateParameters[i];
|
|
1554
|
+
const aValues = oStartupParameters && oStartupParameters[sCreateParameter];
|
|
1555
|
+
if (aValues && aValues.length === 1) {
|
|
1556
|
+
oRet = oRet || Object.create(null);
|
|
1557
|
+
oRet[sCreateParameter] = aValues[0];
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
return oRet;
|
|
1561
|
+
}
|
|
1562
|
+
function getSemanticObjectMapping(oOutbound: any) {
|
|
1563
|
+
const aSemanticObjectMapping: any[] = [];
|
|
1564
|
+
if (oOutbound.parameters) {
|
|
1565
|
+
const aParameters = Object.keys(oOutbound.parameters) || [];
|
|
1566
|
+
if (aParameters.length > 0) {
|
|
1567
|
+
aParameters.forEach(function(sParam: string) {
|
|
1568
|
+
const oMapping = oOutbound.parameters[sParam];
|
|
1569
|
+
if (oMapping.value && oMapping.value.value && oMapping.value.format === "binding") {
|
|
1570
|
+
// using the format of UI.Mapping
|
|
1571
|
+
const oSemanticMapping = {
|
|
1572
|
+
"LocalProperty": {
|
|
1573
|
+
"$PropertyPath": oMapping.value.value
|
|
1574
|
+
},
|
|
1575
|
+
"SemanticObjectProperty": sParam
|
|
1576
|
+
};
|
|
1577
|
+
|
|
1578
|
+
if (aSemanticObjectMapping.length > 0) {
|
|
1579
|
+
// To check if the semanticObject Mapping is done for the same local property more that once then first one will be considered
|
|
1580
|
+
for (let i = 0; i < aSemanticObjectMapping.length; i++) {
|
|
1581
|
+
if (
|
|
1582
|
+
aSemanticObjectMapping[i]["LocalProperty"]["$PropertyPath"] !==
|
|
1583
|
+
oSemanticMapping["LocalProperty"]["$PropertyPath"]
|
|
1584
|
+
) {
|
|
1585
|
+
aSemanticObjectMapping.push(oSemanticMapping);
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
} else {
|
|
1589
|
+
aSemanticObjectMapping.push(oSemanticMapping);
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
return aSemanticObjectMapping;
|
|
1596
|
+
}
|
|
1597
|
+
function getHeaderFacetItemConfigForExternalNavigation(oViewData: any, oCrossNav: any) {
|
|
1598
|
+
const oHeaderFacetItems: any = {};
|
|
1599
|
+
let sId;
|
|
1600
|
+
const oControlConfig = oViewData.controlConfiguration;
|
|
1601
|
+
for (const config in oControlConfig) {
|
|
1602
|
+
if (config.indexOf("@com.sap.vocabularies.UI.v1.DataPoint") > -1 || config.indexOf("@com.sap.vocabularies.UI.v1.Chart") > -1) {
|
|
1603
|
+
if (
|
|
1604
|
+
oControlConfig[config].navigation &&
|
|
1605
|
+
oControlConfig[config].navigation.targetOutbound &&
|
|
1606
|
+
oControlConfig[config].navigation.targetOutbound.outbound
|
|
1607
|
+
) {
|
|
1608
|
+
const sOutbound = oControlConfig[config].navigation.targetOutbound.outbound;
|
|
1609
|
+
const oOutbound = oCrossNav[sOutbound];
|
|
1610
|
+
if (oOutbound.semanticObject && oOutbound.action) {
|
|
1611
|
+
if (config.indexOf("Chart") > -1) {
|
|
1612
|
+
sId = generate(["fe", "MicroChartLink", config]);
|
|
1613
|
+
} else {
|
|
1614
|
+
sId = generate(["fe", "HeaderDPLink", config]);
|
|
1615
|
+
}
|
|
1616
|
+
const aSemanticObjectMapping = CommonUtils.getSemanticObjectMapping(oOutbound);
|
|
1617
|
+
oHeaderFacetItems[sId] = {
|
|
1618
|
+
semanticObject: oOutbound.semanticObject,
|
|
1619
|
+
action: oOutbound.action,
|
|
1620
|
+
semanticObjectMapping: aSemanticObjectMapping
|
|
1621
|
+
};
|
|
1622
|
+
} else {
|
|
1623
|
+
Log.error("Cross navigation outbound is configured without semantic object and action for " + sOutbound);
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
return oHeaderFacetItems;
|
|
1629
|
+
}
|
|
1630
|
+
function setSemanticObjectMappings(oSelectionVariant: any, vMappings: object) {
|
|
1631
|
+
const oMappings = typeof vMappings === "string" ? JSON.parse(vMappings) : vMappings;
|
|
1632
|
+
for (let i = 0; i < oMappings.length; i++) {
|
|
1633
|
+
const sLocalProperty =
|
|
1634
|
+
(oMappings[i]["LocalProperty"] && oMappings[i]["LocalProperty"]["$PropertyPath"]) ||
|
|
1635
|
+
(oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"] &&
|
|
1636
|
+
oMappings[i]["@com.sap.vocabularies.Common.v1.LocalProperty"]["$Path"]);
|
|
1637
|
+
const sSemanticObjectProperty =
|
|
1638
|
+
oMappings[i]["SemanticObjectProperty"] || oMappings[i]["@com.sap.vocabularies.Common.v1.SemanticObjectProperty"];
|
|
1639
|
+
if (oSelectionVariant.getSelectOption(sLocalProperty)) {
|
|
1640
|
+
const oSelectOption = oSelectionVariant.getSelectOption(sLocalProperty);
|
|
1641
|
+
|
|
1642
|
+
//Create a new SelectOption with sSemanticObjectProperty as the property Name and remove the older one
|
|
1643
|
+
oSelectionVariant.removeSelectOption(sLocalProperty);
|
|
1644
|
+
oSelectionVariant.massAddSelectOption(sSemanticObjectProperty, oSelectOption);
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
return oSelectionVariant;
|
|
1648
|
+
}
|
|
1649
|
+
function fnGetSemanticObjectsFromPath(oMetaModel: any, sPath: any) {
|
|
1650
|
+
return new Promise(function(resolve: (value: any) => void) {
|
|
1651
|
+
const sSemanticObject = oMetaModel.getObject(sPath + "@com.sap.vocabularies.Common.v1.SemanticObject");
|
|
1652
|
+
const aSemanticObjectUnavailableActions = oMetaModel.getObject(
|
|
1653
|
+
sPath + "@com.sap.vocabularies.Common.v1.SemanticObjectUnavailableActions"
|
|
1654
|
+
);
|
|
1655
|
+
const aSemanticObjectForGetLinks = [{ semanticObject: sSemanticObject }];
|
|
1656
|
+
const oSemanticObject = {
|
|
1657
|
+
semanticObject: sSemanticObject
|
|
1658
|
+
};
|
|
1659
|
+
resolve({
|
|
1660
|
+
semanticObjectPath: sPath,
|
|
1661
|
+
semanticObjectForGetLinks: aSemanticObjectForGetLinks,
|
|
1662
|
+
semanticObject: oSemanticObject,
|
|
1663
|
+
unavailableActions: aSemanticObjectUnavailableActions
|
|
1664
|
+
});
|
|
1665
|
+
}).catch(function(oError: any) {
|
|
1666
|
+
Log.error("Error in fnGetSemanticObjectsFromPath", oError);
|
|
1667
|
+
});
|
|
1668
|
+
}
|
|
1669
|
+
function fnUpdateSemanticTargetsModel(aGetLinksPromises: any, aSemanticObjects: any, oInternalModelContext: any, sCurrentHash: any) {
|
|
1670
|
+
return Promise.all(aGetLinksPromises)
|
|
1671
|
+
.then(function(aValues: [any, any, any, any, any, any, any, any, any, any]) {
|
|
1672
|
+
let aLinks,
|
|
1673
|
+
_oLink,
|
|
1674
|
+
_sLinkIntentAction,
|
|
1675
|
+
aFinalLinks: any[] = [];
|
|
1676
|
+
let oFinalSemanticObjects: any = {};
|
|
1677
|
+
const bIntentHasActions = function(sIntent: any, aActions: any) {
|
|
1678
|
+
for (const intent in aActions) {
|
|
1679
|
+
if (intent === sIntent) {
|
|
1680
|
+
return true;
|
|
1681
|
+
} else {
|
|
1682
|
+
return false;
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
};
|
|
1686
|
+
|
|
1687
|
+
for (let k = 0; k < aValues.length; k++) {
|
|
1688
|
+
aLinks = aValues[k];
|
|
1689
|
+
if (aLinks && aLinks.length > 0 && aLinks[0] !== undefined) {
|
|
1690
|
+
const oSemanticObject: any = {};
|
|
1691
|
+
let oTmp = {};
|
|
1692
|
+
let sAlternatePath;
|
|
1693
|
+
for (let i = 0; i < aLinks.length; i++) {
|
|
1694
|
+
aFinalLinks.push([]);
|
|
1695
|
+
let hasTargetsNotFiltered = false;
|
|
1696
|
+
let hasTargets = false;
|
|
1697
|
+
for (let iLinkCount = 0; iLinkCount < aLinks[i][0].length; iLinkCount++) {
|
|
1698
|
+
_oLink = aLinks[i][0][iLinkCount];
|
|
1699
|
+
_sLinkIntentAction = _oLink && _oLink.intent.split("?")[0].split("-")[1];
|
|
1700
|
+
|
|
1701
|
+
if (!(_oLink && _oLink.intent && _oLink.intent.indexOf(sCurrentHash) === 0)) {
|
|
1702
|
+
hasTargetsNotFiltered = true;
|
|
1703
|
+
if (!bIntentHasActions(_sLinkIntentAction, aSemanticObjects[k].unavailableActions)) {
|
|
1704
|
+
aFinalLinks[i].push(_oLink);
|
|
1705
|
+
hasTargets = true;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
oTmp = {
|
|
1710
|
+
semanticObject: aSemanticObjects[k].semanticObject,
|
|
1711
|
+
path: aSemanticObjects[k].path,
|
|
1712
|
+
HasTargets: hasTargets,
|
|
1713
|
+
HasTargetsNotFiltered: hasTargetsNotFiltered
|
|
1714
|
+
};
|
|
1715
|
+
if (oSemanticObject[aSemanticObjects[k].semanticObject] === undefined) {
|
|
1716
|
+
oSemanticObject[aSemanticObjects[k].semanticObject] = {};
|
|
1717
|
+
}
|
|
1718
|
+
sAlternatePath = aSemanticObjects[k].path.replace(/\//g, "_");
|
|
1719
|
+
if (oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] === undefined) {
|
|
1720
|
+
oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] = {};
|
|
1721
|
+
}
|
|
1722
|
+
oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath] = Object.assign(
|
|
1723
|
+
oSemanticObject[aSemanticObjects[k].semanticObject][sAlternatePath],
|
|
1724
|
+
oTmp
|
|
1725
|
+
);
|
|
1726
|
+
}
|
|
1727
|
+
const sSemanticObjectName = Object.keys(oSemanticObject)[0];
|
|
1728
|
+
if (Object.keys(oFinalSemanticObjects).includes(sSemanticObjectName)) {
|
|
1729
|
+
oFinalSemanticObjects[sSemanticObjectName] = Object.assign(
|
|
1730
|
+
oFinalSemanticObjects[sSemanticObjectName],
|
|
1731
|
+
oSemanticObject[sSemanticObjectName]
|
|
1732
|
+
);
|
|
1733
|
+
} else {
|
|
1734
|
+
oFinalSemanticObjects = Object.assign(oFinalSemanticObjects, oSemanticObject);
|
|
1735
|
+
}
|
|
1736
|
+
aFinalLinks = [];
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
if (Object.keys(oFinalSemanticObjects).length > 0) {
|
|
1740
|
+
oInternalModelContext.setProperty(
|
|
1741
|
+
"semanticsTargets",
|
|
1742
|
+
mergeObjects(oFinalSemanticObjects, oInternalModelContext.getProperty("semanticsTargets"))
|
|
1743
|
+
);
|
|
1744
|
+
return oFinalSemanticObjects;
|
|
1745
|
+
}
|
|
1746
|
+
})
|
|
1747
|
+
.catch(function(oError: any) {
|
|
1748
|
+
Log.error("fnUpdateSemanticTargetsModel: Cannot read links", oError);
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
function fnGetSemanticObjectPromise(oAppComponent: any, oView: any, oMetaModel: any, sPath: any) {
|
|
1752
|
+
return CommonUtils.getSemanticObjectsFromPath(oMetaModel, sPath);
|
|
1753
|
+
}
|
|
1754
|
+
function fnGetSemanticTargetsFromPageModel(oController: any, sPageModel: string) {
|
|
1755
|
+
const _fnfindValuesHelper = function(obj: any, key: any, list: any) {
|
|
1756
|
+
if (!obj) {
|
|
1757
|
+
return list;
|
|
1758
|
+
}
|
|
1759
|
+
if (obj instanceof Array) {
|
|
1760
|
+
for (const i in obj) {
|
|
1761
|
+
list = list.concat(_fnfindValuesHelper(obj[i], key, []));
|
|
1762
|
+
}
|
|
1763
|
+
return list;
|
|
1764
|
+
}
|
|
1765
|
+
if (obj[key]) {
|
|
1766
|
+
list.push(obj[key]);
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
if (typeof obj == "object" && obj !== null) {
|
|
1770
|
+
const children = Object.keys(obj);
|
|
1771
|
+
if (children.length > 0) {
|
|
1772
|
+
for (let i = 0; i < children.length; i++) {
|
|
1773
|
+
list = list.concat(_fnfindValuesHelper(obj[children[i]], key, []));
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
return list;
|
|
1778
|
+
};
|
|
1779
|
+
const _fnfindValues = function(obj: any, key: any) {
|
|
1780
|
+
return _fnfindValuesHelper(obj, key, []);
|
|
1781
|
+
};
|
|
1782
|
+
const _fnDeleteDuplicateSemanticObjects = function(aSemanticObjectPath: any) {
|
|
1783
|
+
return aSemanticObjectPath.filter(function(value: any, index: any) {
|
|
1784
|
+
return aSemanticObjectPath.indexOf(value) === index;
|
|
1785
|
+
});
|
|
1786
|
+
};
|
|
1787
|
+
const oView = oController.getView();
|
|
1788
|
+
const oInternalModelContext = oView.getBindingContext("internal");
|
|
1789
|
+
|
|
1790
|
+
if (oInternalModelContext) {
|
|
1791
|
+
const aSemanticObjectsPromises = [];
|
|
1792
|
+
const oComponent = oController.getOwnerComponent();
|
|
1793
|
+
const oAppComponent = Component.getOwnerComponentFor(oComponent) as AppComponent;
|
|
1794
|
+
const oMetaModel = oAppComponent.getMetaModel();
|
|
1795
|
+
let oPageModel = oComponent.getModel(sPageModel).getData();
|
|
1796
|
+
if (JSON.stringify(oPageModel) === "{}") {
|
|
1797
|
+
oPageModel = oComponent.getModel(sPageModel)._getObject("/", undefined);
|
|
1798
|
+
}
|
|
1799
|
+
let aSemanticObjectsFound = _fnfindValues(oPageModel, "semanticObjectPath");
|
|
1800
|
+
aSemanticObjectsFound = _fnDeleteDuplicateSemanticObjects(aSemanticObjectsFound);
|
|
1801
|
+
const oShellServiceHelper = CommonUtils.getShellServices(oAppComponent);
|
|
1802
|
+
let sCurrentHash = CommonUtils.getHash();
|
|
1803
|
+
const aSemanticObjectsForGetLinks = [];
|
|
1804
|
+
const aSemanticObjects: any[] = [];
|
|
1805
|
+
let sPath;
|
|
1806
|
+
let _oSemanticObject;
|
|
1807
|
+
|
|
1808
|
+
if (sCurrentHash && sCurrentHash.indexOf("?") !== -1) {
|
|
1809
|
+
// sCurrentHash can contain query string, cut it off!
|
|
1810
|
+
sCurrentHash = sCurrentHash.split("?")[0];
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
for (let i = 0; i < aSemanticObjectsFound.length; i++) {
|
|
1814
|
+
sPath = aSemanticObjectsFound[i];
|
|
1815
|
+
aSemanticObjectsPromises.push(CommonUtils.getSemanticObjectPromise(oAppComponent, oView, oMetaModel, sPath));
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
if (aSemanticObjectsPromises.length === 0) {
|
|
1819
|
+
return Promise.resolve();
|
|
1820
|
+
} else {
|
|
1821
|
+
Promise.all(aSemanticObjectsPromises)
|
|
1822
|
+
.then(function(aValues: any[]) {
|
|
1823
|
+
const aGetLinksPromises = [];
|
|
1824
|
+
let sSemObjExpression;
|
|
1825
|
+
const aSemanticObjectsResolved = aValues.filter(function(element: any) {
|
|
1826
|
+
if (
|
|
1827
|
+
element.semanticObject !== undefined &&
|
|
1828
|
+
element.semanticObject.semanticObject &&
|
|
1829
|
+
typeof element.semanticObject.semanticObject === "object"
|
|
1830
|
+
) {
|
|
1831
|
+
sSemObjExpression = compileBinding(bindingExpression(element.semanticObject.semanticObject.$Path));
|
|
1832
|
+
element.semanticObject.semanticObject = sSemObjExpression;
|
|
1833
|
+
element.semanticObjectForGetLinks[0].semanticObject = sSemObjExpression;
|
|
1834
|
+
return true;
|
|
1835
|
+
} else if (element) {
|
|
1836
|
+
return element.semanticObject !== undefined;
|
|
1837
|
+
} else {
|
|
1838
|
+
return false;
|
|
1839
|
+
}
|
|
1840
|
+
});
|
|
1841
|
+
for (let j = 0; j < aSemanticObjectsResolved.length; j++) {
|
|
1842
|
+
_oSemanticObject = aSemanticObjectsResolved[j];
|
|
1843
|
+
if (
|
|
1844
|
+
_oSemanticObject &&
|
|
1845
|
+
_oSemanticObject.semanticObject &&
|
|
1846
|
+
!(_oSemanticObject.semanticObject.semanticObject.indexOf("{") === 0)
|
|
1847
|
+
) {
|
|
1848
|
+
aSemanticObjectsForGetLinks.push(_oSemanticObject.semanticObjectForGetLinks);
|
|
1849
|
+
aSemanticObjects.push({
|
|
1850
|
+
semanticObject: _oSemanticObject.semanticObject.semanticObject,
|
|
1851
|
+
unavailableActions: _oSemanticObject.unavailableActions,
|
|
1852
|
+
path: aSemanticObjectsResolved[j].semanticObjectPath
|
|
1853
|
+
});
|
|
1854
|
+
aGetLinksPromises.push(oShellServiceHelper.getLinksWithCache([_oSemanticObject.semanticObjectForGetLinks]));
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
return CommonUtils.updateSemanticTargets(aGetLinksPromises, aSemanticObjects, oInternalModelContext, sCurrentHash);
|
|
1858
|
+
})
|
|
1859
|
+
.catch(function(oError: any) {
|
|
1860
|
+
Log.error("fnGetSemanticTargetsFromTable: Cannot get Semantic Objects", oError);
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
} else {
|
|
1864
|
+
return Promise.resolve();
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
function getFilterRestrictions(oFilterRestrictionsAnnotation: any, sRestriction: any) {
|
|
1868
|
+
const FilterRestrictions = CommonUtils.FilterRestrictions;
|
|
1869
|
+
if (sRestriction === FilterRestrictions.REQUIRED_PROPERTIES || sRestriction === FilterRestrictions.NON_FILTERABLE_PROPERTIES) {
|
|
1870
|
+
let aProps = [];
|
|
1871
|
+
if (oFilterRestrictionsAnnotation && oFilterRestrictionsAnnotation[sRestriction]) {
|
|
1872
|
+
aProps = oFilterRestrictionsAnnotation[sRestriction].map(function(oProperty: any) {
|
|
1873
|
+
return oProperty.$PropertyPath;
|
|
1874
|
+
});
|
|
1875
|
+
}
|
|
1876
|
+
return aProps;
|
|
1877
|
+
} else if (sRestriction === FilterRestrictions.ALLOWED_EXPRESSIONS) {
|
|
1878
|
+
const mAllowedExpressions: any = {};
|
|
1879
|
+
if (oFilterRestrictionsAnnotation && oFilterRestrictionsAnnotation.FilterExpressionRestrictions) {
|
|
1880
|
+
oFilterRestrictionsAnnotation.FilterExpressionRestrictions.forEach(function(oProperty: any) {
|
|
1881
|
+
//SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
|
|
1882
|
+
if (mAllowedExpressions[oProperty.Property.$PropertyPath]) {
|
|
1883
|
+
mAllowedExpressions[oProperty.Property.$PropertyPath].push(oProperty.AllowedExpressions);
|
|
1884
|
+
} else {
|
|
1885
|
+
mAllowedExpressions[oProperty.Property.$PropertyPath] = [oProperty.AllowedExpressions];
|
|
1886
|
+
}
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1889
|
+
return mAllowedExpressions;
|
|
1890
|
+
}
|
|
1891
|
+
// Default return the FilterRestrictions Annotation
|
|
1892
|
+
return oFilterRestrictionsAnnotation;
|
|
1893
|
+
}
|
|
1894
|
+
function getFilterRestrictionsByPath(sEntitySetPath: any, oMetaModel: any) {
|
|
1895
|
+
const oRet: any = {},
|
|
1896
|
+
FilterRestrictions = CommonUtils.FilterRestrictions,
|
|
1897
|
+
oFilterRestrictions = sEntitySetPath ? oMetaModel.getObject(sEntitySetPath + "@Org.OData.Capabilities.V1.FilterRestrictions") : {};
|
|
1898
|
+
oRet[FilterRestrictions.REQUIRED_PROPERTIES] = getFilterRestrictions(oFilterRestrictions, FilterRestrictions.REQUIRED_PROPERTIES) || [];
|
|
1899
|
+
oRet[FilterRestrictions.NON_FILTERABLE_PROPERTIES] =
|
|
1900
|
+
getFilterRestrictions(oFilterRestrictions, FilterRestrictions.NON_FILTERABLE_PROPERTIES) || [];
|
|
1901
|
+
//SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
|
|
1902
|
+
oRet[FilterRestrictions.ALLOWED_EXPRESSIONS] = getFilterRestrictions(oFilterRestrictions, FilterRestrictions.ALLOWED_EXPRESSIONS) || {};
|
|
1903
|
+
|
|
1904
|
+
const aPathParts = sEntitySetPath.split("/");
|
|
1905
|
+
|
|
1906
|
+
if (aPathParts.length > 2) {
|
|
1907
|
+
// In normal filterbar scenarios sEntitySetPath is of the format "/Customer".
|
|
1908
|
+
// But, In case of sEntitySetPath of format "/Customer/Set" this is to check navigation restrictions of "Customer" for non-filterable properties in "Set"
|
|
1909
|
+
const sNavigationPath = aPathParts[aPathParts.length - 1];
|
|
1910
|
+
aPathParts.splice(-1, 1); // removing NavigationProperty from the end.
|
|
1911
|
+
const sParentEntitySetPath = aPathParts.join("/");
|
|
1912
|
+
const oNavigationRestrictions = CommonUtils.getNavigationRestrictions(oMetaModel, sParentEntitySetPath, sNavigationPath);
|
|
1913
|
+
const oNavigationFilterRestrictions = oNavigationRestrictions && oNavigationRestrictions["FilterRestrictions"];
|
|
1914
|
+
oRet[FilterRestrictions.REQUIRED_PROPERTIES].concat(
|
|
1915
|
+
getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.REQUIRED_PROPERTIES) || []
|
|
1916
|
+
);
|
|
1917
|
+
oRet[FilterRestrictions.NON_FILTERABLE_PROPERTIES].concat(
|
|
1918
|
+
getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.NON_FILTERABLE_PROPERTIES) || []
|
|
1919
|
+
);
|
|
1920
|
+
//SingleValue | MultiValue | SingleRange | MultiRange | SearchExpression | MultiRangeOrSearchExpression
|
|
1921
|
+
oRet[FilterRestrictions.ALLOWED_EXPRESSIONS] = mergeObjects(
|
|
1922
|
+
{},
|
|
1923
|
+
getFilterRestrictions(oNavigationFilterRestrictions, FilterRestrictions.ALLOWED_EXPRESSIONS) || {},
|
|
1924
|
+
oRet[FilterRestrictions.ALLOWED_EXPRESSIONS]
|
|
1925
|
+
);
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
return oRet;
|
|
1929
|
+
}
|
|
1930
|
+
function templateControlFragment(sFragmentName: any, oPreprocessorSettings: any, oOptions: any, oModifier: any) {
|
|
1931
|
+
oOptions = oOptions || {};
|
|
1932
|
+
if (oModifier) {
|
|
1933
|
+
return oModifier.templateControlFragment(sFragmentName, oPreprocessorSettings, oOptions.view).then(function(oFragment: any) {
|
|
1934
|
+
// This is required as Flex returns an HTMLCollection as templating result in XML time.
|
|
1935
|
+
return oModifier.targets === "xmlTree" && oFragment.length > 0 ? oFragment[0] : oFragment;
|
|
1936
|
+
});
|
|
1937
|
+
} else {
|
|
1938
|
+
return loadMacroLibrary()
|
|
1939
|
+
.then(function() {
|
|
1940
|
+
return XMLPreprocessor.process(
|
|
1941
|
+
XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
|
|
1942
|
+
{ name: sFragmentName },
|
|
1943
|
+
oPreprocessorSettings
|
|
1944
|
+
);
|
|
1945
|
+
})
|
|
1946
|
+
.then(function(oFragment: any) {
|
|
1947
|
+
const oControl = oFragment.firstElementChild;
|
|
1948
|
+
if (!!oOptions.isXML && oControl) {
|
|
1949
|
+
return oControl;
|
|
1950
|
+
}
|
|
1951
|
+
return Fragment.load({
|
|
1952
|
+
id: oOptions.id,
|
|
1953
|
+
definition: oFragment,
|
|
1954
|
+
controller: oOptions.controller
|
|
1955
|
+
});
|
|
1956
|
+
});
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
function requestSingletonProperty(sPath: string, oModel: ODataModel) {
|
|
1960
|
+
if (!sPath || !oModel) {
|
|
1961
|
+
return Promise.resolve(null);
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
const oMetaModel = oModel.getMetaModel();
|
|
1965
|
+
// Find the underlying entity set from the property path and check whether it is a singleton.
|
|
1966
|
+
const aParts = sPath.split("/").filter(Boolean),
|
|
1967
|
+
sPropertyName = aParts.pop(),
|
|
1968
|
+
sNavigationPath = aParts.join("/"),
|
|
1969
|
+
oEntitySet = sNavigationPath && oMetaModel.getObject("/" + sNavigationPath);
|
|
1970
|
+
if (oEntitySet && oEntitySet.$kind === "Singleton") {
|
|
1971
|
+
const sSingletonName = aParts[aParts.length - 1],
|
|
1972
|
+
oPropertyBinding = oModel.bindProperty("/" + sSingletonName + "/" + sPropertyName);
|
|
1973
|
+
return oPropertyBinding.requestValue();
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
return Promise.resolve(null);
|
|
1977
|
+
}
|
|
1978
|
+
function addEventToBindingInfo(oControl: Control, sEventName: string, fHandler: Function) {
|
|
1979
|
+
let oBindingInfo: any;
|
|
1980
|
+
const setBindingInfo = function() {
|
|
1981
|
+
if (oBindingInfo) {
|
|
1982
|
+
if (!oBindingInfo.events) {
|
|
1983
|
+
oBindingInfo.events = {};
|
|
1984
|
+
}
|
|
1985
|
+
if (!oBindingInfo.events[sEventName]) {
|
|
1986
|
+
oBindingInfo.events[sEventName] = fHandler;
|
|
1987
|
+
} else {
|
|
1988
|
+
const fOriginalHandler = oBindingInfo.events[sEventName];
|
|
1989
|
+
oBindingInfo.events[sEventName] = function(...args: any[]) {
|
|
1990
|
+
fHandler.apply(this, ...args);
|
|
1991
|
+
fOriginalHandler.apply(this, ...args);
|
|
1992
|
+
};
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
};
|
|
1996
|
+
if (oControl.isA("sap.ui.mdc.Chart")) {
|
|
1997
|
+
(oControl as any)
|
|
1998
|
+
.innerChartBound()
|
|
1999
|
+
.then(function() {
|
|
2000
|
+
oBindingInfo = (oControl as any)
|
|
2001
|
+
.getControlDelegate()
|
|
2002
|
+
._getChart(oControl)
|
|
2003
|
+
.getBindingInfo("data");
|
|
2004
|
+
setBindingInfo();
|
|
2005
|
+
})
|
|
2006
|
+
.catch(function(sError: any) {
|
|
2007
|
+
Log.error(sError);
|
|
2008
|
+
});
|
|
2009
|
+
} else {
|
|
2010
|
+
oBindingInfo = oControl.data("rowsBindingInfo");
|
|
2011
|
+
setBindingInfo();
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
function loadMacroLibrary() {
|
|
2015
|
+
return new Promise<void>(function(resolve) {
|
|
2016
|
+
sap.ui.require(["sap/fe/macros/macroLibrary"], function(/*macroLibrary*/) {
|
|
2017
|
+
resolve();
|
|
2018
|
+
});
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
2021
|
+
const CommonUtils = {
|
|
2022
|
+
isPropertyFilterable: isPropertyFilterable,
|
|
2023
|
+
isFieldControlPathInapplicable: isFieldControlPathInapplicable,
|
|
2024
|
+
removeSensitiveData: removeSensitiveData,
|
|
2025
|
+
fireButtonPress: fnFireButtonPress,
|
|
2026
|
+
getTargetView: getTargetView,
|
|
2027
|
+
hasTransientContext: fnHasTransientContexts,
|
|
2028
|
+
updateRelatedAppsDetails: fnUpdateRelatedAppsDetails,
|
|
2029
|
+
resolveStringtoBoolean: fnResolveStringtoBoolean,
|
|
2030
|
+
getAppComponent: getAppComponent,
|
|
2031
|
+
processDataLossConfirmation: fnProcessDataLossConfirmation,
|
|
2032
|
+
getMandatoryFilterFields: fnGetMandatoryFilterFields,
|
|
2033
|
+
getContextPathProperties: fnGetContextPathProperties,
|
|
2034
|
+
getParameterInfo: getParameterInfo,
|
|
2035
|
+
updateDataFieldForIBNButtonsVisibility: fnUpdateDataFieldForIBNButtonsVisibility,
|
|
2036
|
+
getTranslatedText: getTranslatedText,
|
|
2037
|
+
getEntitySetName: getEntitySetName,
|
|
2038
|
+
getActionPath: getActionPath,
|
|
2039
|
+
computeDisplayMode: computeDisplayMode,
|
|
2040
|
+
setActionEnablement: setActionEnablement,
|
|
2041
|
+
isStickyEditMode: isStickyEditMode,
|
|
2042
|
+
getOperatorsForProperty: getOperatorsForProperty,
|
|
2043
|
+
addSelectionVariantToConditions: addSelectionVariantToConditions,
|
|
2044
|
+
addExternalStateFiltersToSelectionVariant: addExternalStateFiltersToSelectionVariant,
|
|
2045
|
+
addPageContextToSelectionVariant: addPageContextToSelectionVariant,
|
|
2046
|
+
addDefaultDisplayCurrency: addDefaultDisplayCurrency,
|
|
2047
|
+
getNonComputedVisibleFields: getNonComputedVisibleFields,
|
|
2048
|
+
setUserDefaults: setUserDefaults,
|
|
2049
|
+
getShellServices: getShellServices,
|
|
2050
|
+
getHash: getHash,
|
|
2051
|
+
getIBNActions: fnGetIBNActions,
|
|
2052
|
+
getHeaderFacetItemConfigForExternalNavigation: getHeaderFacetItemConfigForExternalNavigation,
|
|
2053
|
+
getSemanticObjectMapping: getSemanticObjectMapping,
|
|
2054
|
+
setSemanticObjectMappings: setSemanticObjectMappings,
|
|
2055
|
+
getSemanticObjectPromise: fnGetSemanticObjectPromise,
|
|
2056
|
+
getSemanticTargetsFromPageModel: fnGetSemanticTargetsFromPageModel,
|
|
2057
|
+
getSemanticObjectsFromPath: fnGetSemanticObjectsFromPath,
|
|
2058
|
+
updateSemanticTargets: fnUpdateSemanticTargetsModel,
|
|
2059
|
+
getPropertyDataType: getPropertyDataType,
|
|
2060
|
+
getNavigationRestrictions: getNavigationRestrictions,
|
|
2061
|
+
getSearchRestrictions: getSearchRestrictions,
|
|
2062
|
+
getFilterRestrictionsByPath: getFilterRestrictionsByPath,
|
|
2063
|
+
getSpecificAllowedExpression: getSpecificAllowedExpression,
|
|
2064
|
+
getAdditionalParamsForCreate: getAdditionalParamsForCreate,
|
|
2065
|
+
requestSingletonProperty: requestSingletonProperty,
|
|
2066
|
+
templateControlFragment: templateControlFragment,
|
|
2067
|
+
addEventToBindingInfo: addEventToBindingInfo,
|
|
2068
|
+
FilterRestrictions: {
|
|
2069
|
+
REQUIRED_PROPERTIES: "RequiredProperties",
|
|
2070
|
+
NON_FILTERABLE_PROPERTIES: "NonFilterableProperties",
|
|
2071
|
+
ALLOWED_EXPRESSIONS: "FilterAllowedExpressions"
|
|
2072
|
+
},
|
|
2073
|
+
AllowedExpressionsPrio: ["SingleValue", "MultiValue", "SingleRange", "MultiRange", "SearchExpression", "MultiRangeOrSearchExpression"],
|
|
2074
|
+
fnProcessDataLossOrDraftDiscardConfirmation: fnProcessDataLossOrDraftDiscardConfirmation,
|
|
2075
|
+
normalizeSearchTerm: normalizeSearchTerm
|
|
2076
|
+
};
|
|
2077
|
+
|
|
2078
|
+
export default CommonUtils;
|