@sapui5/sap.fe.core 1.96.4 → 1.99.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -5
- 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 +5 -3
- package/src/sap/fe/core/AppStateHandler.js +229 -195
- 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 -2606
- 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 -809
- 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 +63 -0
- package/src/sap/fe/core/TransactionHelper.js +1576 -1627
- package/src/sap/fe/core/TransactionHelper.ts +1706 -0
- package/src/sap/fe/core/actions/draft.js +559 -581
- package/src/sap/fe/core/actions/draft.ts +593 -0
- package/src/sap/fe/core/actions/messageHandling.js +545 -435
- 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 -1192
- 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 +235 -264
- 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 +35 -25
- package/src/sap/fe/core/controllerextensions/InternalRouting.js +79 -46
- package/src/sap/fe/core/controllerextensions/KPIManagement.js +86 -10
- package/src/sap/fe/core/controllerextensions/KPIManagement.ts +109 -31
- package/src/sap/fe/core/controllerextensions/MassEdit.js +172 -0
- package/src/sap/fe/core/controllerextensions/MessageHandler.js +237 -104
- 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 +3 -2
- 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 +36 -8
- 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 +112 -113
- 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 +2 -1
- package/src/sap/fe/core/converters/ManifestSettings.ts +8 -1
- 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 +76 -6
- package/src/sap/fe/core/converters/MetaModelConverter.ts +79 -15
- 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 +85 -46
- package/src/sap/fe/core/converters/controls/Common/Action.js +16 -4
- package/src/sap/fe/core/converters/controls/Common/Action.ts +14 -5
- 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 +60 -19
- package/src/sap/fe/core/converters/controls/Common/Form.ts +66 -14
- 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 +503 -399
- package/src/sap/fe/core/converters/controls/Common/Table.ts +615 -480
- 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 +6 -6
- package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +9 -15
- 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/ID.js +9 -1
- package/src/sap/fe/core/converters/helpers/ID.ts +4 -0
- package/src/sap/fe/core/converters/helpers/IssueManager.js +7 -1
- package/src/sap/fe/core/converters/helpers/IssueManager.ts +6 -0
- package/src/sap/fe/core/converters/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 +29 -11
- package/src/sap/fe/core/converters/templates/ListReportConverter.ts +36 -20
- package/src/sap/fe/core/designtime/AppComponent.designtime.js +13 -3
- 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 +65 -31
- package/src/sap/fe/core/formatters/TableFormatter.ts +62 -30
- 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 +479 -464
- package/src/sap/fe/core/helpers/BindingExpression.ts +477 -483
- 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 +210 -0
- package/src/sap/fe/core/helpers/KeepAliveHelper.ts +202 -0
- package/src/sap/fe/core/helpers/KeepAliveRefreshTypes.js +32 -0
- package/src/sap/fe/core/helpers/KeepAliveRefreshTypes.ts +36 -0
- package/src/sap/fe/core/helpers/MassEditHelper.js +687 -0
- package/src/sap/fe/core/helpers/ModelHelper.js +229 -174
- 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 +72 -10
- package/src/sap/fe/core/messagebundle_ar.properties +41 -0
- package/src/sap/fe/core/messagebundle_bg.properties +41 -0
- package/src/sap/fe/core/messagebundle_ca.properties +41 -0
- package/src/sap/fe/core/messagebundle_cs.properties +42 -1
- package/src/sap/fe/core/messagebundle_cy.properties +41 -0
- package/src/sap/fe/core/messagebundle_da.properties +41 -0
- package/src/sap/fe/core/messagebundle_de.properties +41 -0
- package/src/sap/fe/core/messagebundle_el.properties +41 -0
- package/src/sap/fe/core/messagebundle_en.properties +41 -0
- package/src/sap/fe/core/messagebundle_en_GB.properties +41 -0
- package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +41 -0
- package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +35 -0
- package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +41 -0
- package/src/sap/fe/core/messagebundle_es.properties +41 -0
- package/src/sap/fe/core/messagebundle_es_MX.properties +41 -0
- package/src/sap/fe/core/messagebundle_et.properties +41 -0
- package/src/sap/fe/core/messagebundle_fi.properties +41 -0
- package/src/sap/fe/core/messagebundle_fr.properties +46 -5
- package/src/sap/fe/core/messagebundle_fr_CA.properties +41 -0
- package/src/sap/fe/core/messagebundle_hi.properties +41 -0
- package/src/sap/fe/core/messagebundle_hr.properties +41 -0
- package/src/sap/fe/core/messagebundle_hu.properties +42 -1
- package/src/sap/fe/core/messagebundle_id.properties +45 -4
- package/src/sap/fe/core/messagebundle_it.properties +41 -0
- package/src/sap/fe/core/messagebundle_iw.properties +41 -0
- package/src/sap/fe/core/messagebundle_ja.properties +50 -9
- package/src/sap/fe/core/messagebundle_kk.properties +41 -0
- package/src/sap/fe/core/messagebundle_ko.properties +41 -0
- package/src/sap/fe/core/messagebundle_lt.properties +41 -0
- package/src/sap/fe/core/messagebundle_lv.properties +41 -0
- package/src/sap/fe/core/messagebundle_ms.properties +41 -0
- package/src/sap/fe/core/messagebundle_nl.properties +41 -0
- package/src/sap/fe/core/messagebundle_no.properties +41 -0
- package/src/sap/fe/core/messagebundle_pl.properties +41 -0
- package/src/sap/fe/core/messagebundle_pt.properties +43 -2
- package/src/sap/fe/core/messagebundle_pt_PT.properties +41 -0
- package/src/sap/fe/core/messagebundle_ro.properties +41 -0
- package/src/sap/fe/core/messagebundle_ru.properties +41 -0
- package/src/sap/fe/core/messagebundle_sh.properties +41 -0
- package/src/sap/fe/core/messagebundle_sk.properties +41 -0
- package/src/sap/fe/core/messagebundle_sl.properties +41 -0
- package/src/sap/fe/core/messagebundle_sv.properties +42 -1
- package/src/sap/fe/core/messagebundle_th.properties +41 -0
- package/src/sap/fe/core/messagebundle_tr.properties +41 -0
- package/src/sap/fe/core/messagebundle_uk.properties +41 -0
- package/src/sap/fe/core/messagebundle_vi.properties +41 -0
- package/src/sap/fe/core/messagebundle_zh_CN.properties +41 -0
- package/src/sap/fe/core/messagebundle_zh_TW.properties +41 -0
- 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 -1166
- 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 +41 -84
- package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +56 -99
- 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 +6 -24
- package/src/sap/fe/core/templating/DataModelPathHelper.ts +10 -23
- 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/EntitySetHelper.js +80 -7
- package/src/sap/fe/core/templating/EntitySetHelper.ts +42 -2
- 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 -113
- package/src/sap/fe/core/templating/UIFormatters.ts +39 -76
- 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
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import ODataMetaModel from "sap/ui/model/odata/v4/ODataMetaModel";
|
|
2
|
+
import ODataModel from "sap/ui/model/odata/v4/ODataModel";
|
|
3
|
+
import Context from "sap/ui/model/odata/v4/Context";
|
|
4
|
+
import Filter from "sap/ui/model/Filter";
|
|
5
|
+
import FilterOperator from "sap/ui/model/FilterOperator";
|
|
6
|
+
import Router from "sap/ui/core/routing/Router";
|
|
7
|
+
import ModelHelper from "./ModelHelper";
|
|
8
|
+
|
|
9
|
+
type ValuedKey = {
|
|
10
|
+
name: string;
|
|
11
|
+
value: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type PageInfo = {
|
|
15
|
+
pattern: string;
|
|
16
|
+
contextPath: string;
|
|
17
|
+
draftMode: Boolean;
|
|
18
|
+
technicalKeys: ValuedKey[] | undefined;
|
|
19
|
+
semanticKeys: ValuedKey[] | undefined;
|
|
20
|
+
target: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Retrieves a set of key values from startup parameters.
|
|
25
|
+
*
|
|
26
|
+
* @param aKeyNames The array of key names
|
|
27
|
+
* @param oStartupParameters The startup parameters
|
|
28
|
+
* @returns An array of pairs {name, value} if all key values could be found in the startup parameters, undefined otherwise
|
|
29
|
+
*/
|
|
30
|
+
function _getKeysFromStartupParams(aKeyNames: string[], oStartupParameters: any): ValuedKey[] | undefined {
|
|
31
|
+
let bAllFound = true;
|
|
32
|
+
const aKeys = aKeyNames.map(name => {
|
|
33
|
+
if (oStartupParameters[name] && oStartupParameters[name].length === 1) {
|
|
34
|
+
return { name, value: oStartupParameters[name][0] as string };
|
|
35
|
+
} else {
|
|
36
|
+
// A unique key value couldn't be found in the startup parameters
|
|
37
|
+
bAllFound = false;
|
|
38
|
+
return { name, value: "" };
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return bAllFound ? aKeys : undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Creates a filter from a list of key values.
|
|
47
|
+
*
|
|
48
|
+
* @param aKeys Array of semantic keys or technical keys (with values)
|
|
49
|
+
* @param bDraftMode True if the entity supports draft mode
|
|
50
|
+
* @param oMetaModel The metamodel
|
|
51
|
+
* @returns The filter
|
|
52
|
+
*/
|
|
53
|
+
function _createFilterFromKeys(aKeys: ValuedKey[], bDraftMode: Boolean, oMetaModel: ODataMetaModel): Filter {
|
|
54
|
+
const bFilterCaseSensitive = ModelHelper.isFilteringCaseSensitive(oMetaModel);
|
|
55
|
+
|
|
56
|
+
let bFilterOnActiveEntity = false;
|
|
57
|
+
const aFilters = aKeys.map(key => {
|
|
58
|
+
if (key.name === "IsActiveEntity") {
|
|
59
|
+
bFilterOnActiveEntity = true;
|
|
60
|
+
}
|
|
61
|
+
return new Filter({
|
|
62
|
+
path: key.name,
|
|
63
|
+
operator: FilterOperator.EQ,
|
|
64
|
+
value1: key.value,
|
|
65
|
+
caseSensitive: bFilterCaseSensitive
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
if (bDraftMode && !bFilterOnActiveEntity) {
|
|
69
|
+
const oDraftFilter = new Filter({
|
|
70
|
+
filters: [new Filter("IsActiveEntity", "EQ", false), new Filter("SiblingEntity/IsActiveEntity", "EQ", null)],
|
|
71
|
+
and: false
|
|
72
|
+
});
|
|
73
|
+
aFilters.push(oDraftFilter);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return new Filter(aFilters, true);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Loads all contexts for a list of page infos.
|
|
81
|
+
*
|
|
82
|
+
* @param aStartupPages The list of page infos
|
|
83
|
+
* @param oModel The model used to load the contexts
|
|
84
|
+
* @returns A Promise for all contexts
|
|
85
|
+
*/
|
|
86
|
+
function _requestObjectsFromParameters(aStartupPages: PageInfo[], oModel: ODataModel): Promise<Context[][]> {
|
|
87
|
+
// Load the respective objects for all object pages found in aExternallyNavigablePages
|
|
88
|
+
const aContextPromises = aStartupPages.map(pageInfo => {
|
|
89
|
+
const aKeys = pageInfo.semanticKeys || pageInfo.technicalKeys || [];
|
|
90
|
+
const oFilter = _createFilterFromKeys(aKeys, pageInfo.draftMode, oModel.getMetaModel());
|
|
91
|
+
|
|
92
|
+
// only request a minimum of fields to boost backend performance since this is only used to check if an object exists
|
|
93
|
+
const oListBind = oModel.bindList(pageInfo.contextPath, undefined, undefined, oFilter, {
|
|
94
|
+
"$select": aKeys
|
|
95
|
+
.map(key => {
|
|
96
|
+
return key.name;
|
|
97
|
+
})
|
|
98
|
+
.join(",")
|
|
99
|
+
} as any);
|
|
100
|
+
return oListBind.requestContexts(0, 2);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return Promise.all(aContextPromises);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Returns the list of all pages that allow deeplink and that can be reached using the startup parameters.
|
|
108
|
+
*
|
|
109
|
+
* @param oManifestRouting The routing information from the app manifest
|
|
110
|
+
* @param oStartupParameters The startup parameters
|
|
111
|
+
* @param oMetaModel The metamodel
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
114
|
+
function _getReachablePages(oManifestRouting: any, oStartupParameters: any, oMetaModel: ODataMetaModel): PageInfo[][] {
|
|
115
|
+
const aRoutes: any[] = oManifestRouting.routes;
|
|
116
|
+
const mPagesByLevel: Record<number, PageInfo[]> = {};
|
|
117
|
+
|
|
118
|
+
aRoutes.forEach(oRoute => {
|
|
119
|
+
let sPattern: string = oRoute.pattern.replace(":?query:", "");
|
|
120
|
+
if (sPattern.endsWith("/")) {
|
|
121
|
+
sPattern = sPattern.substr(0, sPattern.length - 1);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (sPattern) {
|
|
125
|
+
// Ignore level-0 routes (ListReport)
|
|
126
|
+
sPattern = sPattern.replace(/\(\{[^\}]*\}\)/g, "(#)"); // Replace keys with #
|
|
127
|
+
|
|
128
|
+
// Get the rightmost target for this route
|
|
129
|
+
const sTargetName: string = Array.isArray(oRoute.target) ? oRoute.target[oRoute.target.length - 1] : oRoute.target;
|
|
130
|
+
const oTarget = oManifestRouting.targets[sTargetName];
|
|
131
|
+
|
|
132
|
+
const aPatternSegments = sPattern.split("/");
|
|
133
|
+
const pageLevel = aPatternSegments.length - 1;
|
|
134
|
+
|
|
135
|
+
// The first level of object page allows deep linking by default.
|
|
136
|
+
// Otherwise, the target must allow deep linking explicitely in the manifest
|
|
137
|
+
if (pageLevel === 0 || oTarget?.options?.settings?.allowDeepLinking) {
|
|
138
|
+
const sContextPath: string =
|
|
139
|
+
oTarget.options.settings.contextPath ||
|
|
140
|
+
(oTarget.options.settings.entitySet && "/" + oTarget.options.settings.entitySet);
|
|
141
|
+
const oEntityType = sContextPath && oMetaModel.getObject("/$EntityContainer" + sContextPath + "/");
|
|
142
|
+
|
|
143
|
+
if (oEntityType) {
|
|
144
|
+
// Get the semantic key values for the entity
|
|
145
|
+
const aSemanticKeyNames: any = oMetaModel.getObject(
|
|
146
|
+
"/$EntityContainer" + sContextPath + "/@com.sap.vocabularies.Common.v1.SemanticKey"
|
|
147
|
+
);
|
|
148
|
+
const aSemantickKeys = aSemanticKeyNames
|
|
149
|
+
? _getKeysFromStartupParams(
|
|
150
|
+
aSemanticKeyNames.map((semKey: any) => {
|
|
151
|
+
return semKey.$PropertyPath as string;
|
|
152
|
+
}),
|
|
153
|
+
oStartupParameters
|
|
154
|
+
)
|
|
155
|
+
: undefined;
|
|
156
|
+
|
|
157
|
+
// Get the technical keys only if we couldn't find the semantic key values, and on first level OP
|
|
158
|
+
const aTechnicalKeys =
|
|
159
|
+
!aSemantickKeys && pageLevel === 0 ? _getKeysFromStartupParams(oEntityType["$Key"], oStartupParameters) : undefined;
|
|
160
|
+
|
|
161
|
+
if (aSemantickKeys || aTechnicalKeys) {
|
|
162
|
+
// The startup parameters contain values for all semantic keys (or technical keys) --> we can store the page info in the corresponding level
|
|
163
|
+
const draftMode =
|
|
164
|
+
oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot") ||
|
|
165
|
+
oMetaModel.getObject("/$EntityContainer" + sContextPath + "@com.sap.vocabularies.Common.v1.DraftNode")
|
|
166
|
+
? true
|
|
167
|
+
: false;
|
|
168
|
+
|
|
169
|
+
if (!mPagesByLevel[pageLevel]) {
|
|
170
|
+
mPagesByLevel[pageLevel] = [];
|
|
171
|
+
}
|
|
172
|
+
mPagesByLevel[pageLevel].push({
|
|
173
|
+
pattern: sPattern,
|
|
174
|
+
contextPath: sContextPath,
|
|
175
|
+
draftMode,
|
|
176
|
+
technicalKeys: aTechnicalKeys,
|
|
177
|
+
semanticKeys: aSemantickKeys,
|
|
178
|
+
target: sTargetName
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// A page is reachable only if all its parents are also reachable
|
|
187
|
+
// So if we couldn't find any pages for a given level, all pages with a higher level won't be reachable anyway
|
|
188
|
+
const aReachablePages: PageInfo[][] = [];
|
|
189
|
+
let level = 0;
|
|
190
|
+
while (mPagesByLevel[level]) {
|
|
191
|
+
aReachablePages.push(mPagesByLevel[level]);
|
|
192
|
+
level++;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return aReachablePages;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Get the list of startup pages.
|
|
200
|
+
*
|
|
201
|
+
* @param oManifestRouting The routing information from the app manifest
|
|
202
|
+
* @param oStartupParameters The startup parameters
|
|
203
|
+
* @param oMetaModel The metamodel
|
|
204
|
+
* @returns An array of startup page infos
|
|
205
|
+
*/
|
|
206
|
+
function _getStartupPagesFromStartupParams(oManifestRouting: any, oStartupParameters: any, oMetaModel: ODataMetaModel): PageInfo[] {
|
|
207
|
+
// Find all pages that can be reached with the startup parameters
|
|
208
|
+
const aReachablePages = _getReachablePages(oManifestRouting, oStartupParameters, oMetaModel);
|
|
209
|
+
|
|
210
|
+
if (aReachablePages.length === 0) {
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Find the longest sequence of pages that can be reached (recursively)
|
|
215
|
+
let result: PageInfo[] = [];
|
|
216
|
+
const current: PageInfo[] = [];
|
|
217
|
+
|
|
218
|
+
function findRecursive(level: number) {
|
|
219
|
+
const aCurrentLevelPages = aReachablePages[level];
|
|
220
|
+
const lastPage = current.length ? current[current.length - 1] : undefined;
|
|
221
|
+
|
|
222
|
+
if (aCurrentLevelPages) {
|
|
223
|
+
aCurrentLevelPages.forEach(function(nextPage) {
|
|
224
|
+
if (!lastPage || nextPage.pattern.indexOf(lastPage.pattern) === 0) {
|
|
225
|
+
// We only consider pages that can be reached from the page at the previous level,
|
|
226
|
+
// --> their pattern must be the pattern of the previous page with another segment appended
|
|
227
|
+
current.push(nextPage);
|
|
228
|
+
findRecursive(level + 1);
|
|
229
|
+
current.pop();
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
if (current.length > result.length) {
|
|
234
|
+
result = current.slice(); // We have found a sequence longer than our previous best --> store it as the new longest
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
findRecursive(0);
|
|
239
|
+
|
|
240
|
+
return result;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Creates the startup object from the list of pages and contexts.
|
|
245
|
+
*
|
|
246
|
+
* @param aStartupPages The pages
|
|
247
|
+
* @param aContexts The contexts
|
|
248
|
+
* @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
|
|
249
|
+
*/
|
|
250
|
+
function _getDeepLinkObject(aStartupPages: PageInfo[], aContexts: Context[]): { hash?: string; context?: Context } {
|
|
251
|
+
if (aContexts.length === 1) {
|
|
252
|
+
return { context: aContexts[0] };
|
|
253
|
+
} else if (aContexts.length > 1) {
|
|
254
|
+
// Navigation to a deeper level --> use the pattern of the deepest object page
|
|
255
|
+
// and replace the parameters by the ID from the contexts
|
|
256
|
+
let hash = aStartupPages[aStartupPages.length - 1].pattern;
|
|
257
|
+
aContexts.forEach(function(oContext) {
|
|
258
|
+
hash = hash.replace("(#)", "(" + oContext.getPath().split("(")[1]);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
return { hash };
|
|
262
|
+
} else {
|
|
263
|
+
return {};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Calculates startup parameters for a deeplink case, from startup parameters and routing infoirmation.
|
|
269
|
+
*
|
|
270
|
+
* @param oManifestRouting The routing information from the app manifest
|
|
271
|
+
* @param oStartupParameters The startup parameters
|
|
272
|
+
* @param oModel The OData model
|
|
273
|
+
* @returns An object containing either a hash or a context to navigate to, or an empty object if no deep link was found
|
|
274
|
+
*/
|
|
275
|
+
function getDeepLinkStartupHash(
|
|
276
|
+
oManifestRouting: any,
|
|
277
|
+
oStartupParameters: any,
|
|
278
|
+
oModel: ODataModel
|
|
279
|
+
): Promise<{ hash?: string; context?: Context }> {
|
|
280
|
+
let aStartupPages: PageInfo[];
|
|
281
|
+
|
|
282
|
+
return oModel
|
|
283
|
+
.getMetaModel()
|
|
284
|
+
.requestObject("/$EntityContainer/")
|
|
285
|
+
.then(() => {
|
|
286
|
+
// Check if semantic keys are present in url parameters for every object page at each level
|
|
287
|
+
aStartupPages = _getStartupPagesFromStartupParams(oManifestRouting, oStartupParameters, oModel.getMetaModel());
|
|
288
|
+
|
|
289
|
+
return _requestObjectsFromParameters(aStartupPages, oModel);
|
|
290
|
+
})
|
|
291
|
+
.then((aValues: Context[][]) => {
|
|
292
|
+
if (aValues.length) {
|
|
293
|
+
// Make sure we only get 1 context per promise, and flatten the array
|
|
294
|
+
const aContexts: Context[] = [];
|
|
295
|
+
aValues.forEach(function(aFoundContexts) {
|
|
296
|
+
if (aFoundContexts.length === 1) {
|
|
297
|
+
aContexts.push(aFoundContexts[0]);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
return aContexts.length === aValues.length ? _getDeepLinkObject(aStartupPages, aContexts) : {};
|
|
302
|
+
} else {
|
|
303
|
+
return {};
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Calculates the new hash based on the startup parameters.
|
|
310
|
+
*
|
|
311
|
+
* @param oStartupParameters The startup parameter values (map parameter name -> array of values)
|
|
312
|
+
* @param sContextPath The context path for the startup of the app (generally the path to the main entity set)
|
|
313
|
+
* @param oRouter The router instance
|
|
314
|
+
* @param oMetaModel The meta model
|
|
315
|
+
* @returns A promise containing the hash to navigate to, or an empty string if there's no need to navigate
|
|
316
|
+
*/
|
|
317
|
+
function getCreateStartupHash(oStartupParameters: any, sContextPath: string, oRouter: Router, oMetaModel: ODataMetaModel): Promise<String> {
|
|
318
|
+
return oMetaModel.requestObject(sContextPath + "@").then(function(oEntitySetAnnotations: any) {
|
|
319
|
+
let sMetaPath = "";
|
|
320
|
+
let bCreatable = true;
|
|
321
|
+
|
|
322
|
+
if (
|
|
323
|
+
oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"] &&
|
|
324
|
+
oEntitySetAnnotations["@com.sap.vocabularies.Common.v1.DraftRoot"]["NewAction"]
|
|
325
|
+
) {
|
|
326
|
+
sMetaPath = sContextPath + "@com.sap.vocabularies.Common.v1.DraftRoot/NewAction@Org.OData.Core.V1.OperationAvailable";
|
|
327
|
+
} else if (
|
|
328
|
+
oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"] &&
|
|
329
|
+
oEntitySetAnnotations["@com.sap.vocabularies.Session.v1.StickySessionSupported"]["NewAction"]
|
|
330
|
+
) {
|
|
331
|
+
sMetaPath =
|
|
332
|
+
sContextPath + "@com.sap.vocabularies.Session.v1.StickySessionSupported/NewAction@Org.OData.Core.V1.OperationAvailable";
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (sMetaPath) {
|
|
336
|
+
const bNewActionOperationAvailable = oMetaModel.getObject(sMetaPath);
|
|
337
|
+
if (bNewActionOperationAvailable === false) {
|
|
338
|
+
bCreatable = false;
|
|
339
|
+
}
|
|
340
|
+
} else {
|
|
341
|
+
const oInsertRestrictions = oEntitySetAnnotations["@Org.OData.Capabilities.V1.InsertRestrictions"];
|
|
342
|
+
if (oInsertRestrictions && oInsertRestrictions.Insertable === false) {
|
|
343
|
+
bCreatable = false;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (bCreatable) {
|
|
347
|
+
return getDefaultCreateHash(oStartupParameters, sContextPath, oRouter);
|
|
348
|
+
} else {
|
|
349
|
+
return "";
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Calculates the hash to create a new object.
|
|
356
|
+
*
|
|
357
|
+
* @param oStartupParameters The startup parameter values (map parameter name -> array of values)
|
|
358
|
+
* @param sContextPath The context path of the entity set to be used for the creation
|
|
359
|
+
* @param oRouter The router instance
|
|
360
|
+
* @returns The hash
|
|
361
|
+
*/
|
|
362
|
+
function getDefaultCreateHash(oStartupParameters: any, sContextPath: string, oRouter: Router): string {
|
|
363
|
+
let sDefaultCreateHash =
|
|
364
|
+
oStartupParameters && oStartupParameters.preferredMode ? (oStartupParameters.preferredMode[0] as string) : "create";
|
|
365
|
+
let sHash = "";
|
|
366
|
+
|
|
367
|
+
sDefaultCreateHash =
|
|
368
|
+
sDefaultCreateHash.indexOf(":") !== -1 && sDefaultCreateHash.length > sDefaultCreateHash.indexOf(":") + 1
|
|
369
|
+
? sDefaultCreateHash.substr(0, sDefaultCreateHash.indexOf(":"))
|
|
370
|
+
: "create";
|
|
371
|
+
sHash = sContextPath.substring(1) + "(...)?i-action=" + sDefaultCreateHash;
|
|
372
|
+
if (oRouter.getRouteInfoByHash(sHash)) {
|
|
373
|
+
return sHash;
|
|
374
|
+
} else {
|
|
375
|
+
throw new Error("No route match for creating a new " + sContextPath.substring(1));
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const AppStartupHelper = {
|
|
380
|
+
_getKeysFromStartupParams,
|
|
381
|
+
_createFilterFromKeys,
|
|
382
|
+
_requestObjectsFromParameters,
|
|
383
|
+
_getReachablePages,
|
|
384
|
+
_getStartupPagesFromStartupParams,
|
|
385
|
+
_getDeepLinkObject,
|
|
386
|
+
getDeepLinkStartupHash,
|
|
387
|
+
getCreateStartupHash,
|
|
388
|
+
getDefaultCreateHash
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
export default AppStartupHelper;
|