@sap-ux/preview-middleware 0.19.7 → 0.19.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/client/adp/controllers/AddSubpage.controller.js +49 -40
  2. package/dist/client/adp/controllers/AddSubpage.controller.ts +79 -62
  3. package/dist/client/adp/init-dialogs.js +52 -21
  4. package/dist/client/adp/init-dialogs.ts +53 -21
  5. package/dist/client/adp/init.js +1 -1
  6. package/dist/client/adp/init.ts +2 -1
  7. package/dist/client/adp/quick-actions/add-new-subpage-quick-action-base.js +98 -0
  8. package/dist/client/adp/quick-actions/add-new-subpage-quick-action-base.ts +138 -0
  9. package/dist/client/adp/quick-actions/common/add-controller-to-page.js +4 -2
  10. package/dist/client/adp/quick-actions/common/add-controller-to-page.ts +5 -8
  11. package/dist/client/adp/quick-actions/fe-v2/add-new-subpage.js +83 -0
  12. package/dist/client/adp/quick-actions/fe-v2/add-new-subpage.ts +88 -0
  13. package/dist/client/adp/quick-actions/fe-v2/registry.js +2 -2
  14. package/dist/client/adp/quick-actions/fe-v2/registry.ts +1 -1
  15. package/dist/client/adp/quick-actions/fe-v4/add-new-subpage.js +132 -0
  16. package/dist/client/adp/quick-actions/fe-v4/add-new-subpage.ts +170 -0
  17. package/dist/client/adp/quick-actions/fe-v4/registry.js +4 -3
  18. package/dist/client/adp/quick-actions/fe-v4/registry.ts +5 -2
  19. package/dist/client/adp/quick-actions/fe-v4/utils.js +25 -0
  20. package/dist/client/adp/quick-actions/fe-v4/utils.ts +29 -0
  21. package/dist/client/adp/quick-actions/supported-ui5versions.md +34 -33
  22. package/dist/client/adp/utils.js +59 -1
  23. package/dist/client/adp/utils.ts +65 -0
  24. package/dist/client/cpe/outline/nodes.js +5 -24
  25. package/dist/client/cpe/outline/nodes.ts +2 -29
  26. package/dist/client/cpe/outline/service.js +3 -23
  27. package/dist/client/cpe/outline/service.ts +6 -25
  28. package/dist/client/cpe/types.ts +1 -0
  29. package/dist/client/cpe/utils.js +1 -28
  30. package/dist/client/cpe/utils.ts +1 -27
  31. package/dist/client/flp/initRta.js +2 -2
  32. package/dist/client/flp/initRta.ts +7 -6
  33. package/dist/client/messagebundle.properties +7 -4
  34. package/dist/client/utils/fe-v4.js +11 -12
  35. package/dist/client/utils/fe-v4.ts +12 -10
  36. package/package.json +7 -7
  37. package/dist/client/adp/quick-actions/common/add-new-subpage.js +0 -140
  38. package/dist/client/adp/quick-actions/common/add-new-subpage.ts +0 -168
@@ -0,0 +1,170 @@
1
+ import ODataModelV4 from 'sap/ui/model/odata/v4/ODataModel';
2
+ import ODataMetaModelV4 from 'sap/ui/model/odata/v4/ODataMetaModel';
3
+ import Component from 'sap/ui/core/Component';
4
+ import AppComponent from 'sap/fe/core/AppComponent';
5
+
6
+ import { getV4AppComponent, getV4ApplicationPages } from '../../../utils/fe-v4';
7
+ import { AddNewSubpageBase, ApplicationPageData } from '../add-new-subpage-quick-action-base';
8
+ import { isA } from '../../../utils/core';
9
+ import FEObjectPageComponent from 'sap/fe/templates/ObjectPage/Component';
10
+ import FEListReportComponent from 'sap/fe/templates/ListReport/Component';
11
+ import { getUi5Version, isLowerThanMinimalUi5Version } from '../../../utils/version';
12
+ import { PageDescriptorV4 } from '../../controllers/AddSubpage.controller';
13
+
14
+ export const OBJECT_PAGE_COMPONENT_NAME_V4 = 'sap.fe.templates.ObjectPage.ObjectPage';
15
+
16
+ interface ViewDataType {
17
+ stableId: string;
18
+ }
19
+
20
+ /**
21
+ * Quick Action for adding a custom page action.
22
+ */
23
+ export class AddNewSubpage extends AddNewSubpageBase<ODataMetaModelV4> {
24
+ protected pageId: string | undefined;
25
+ protected routePattern: string | undefined;
26
+ protected appComponent: AppComponent | undefined;
27
+
28
+ protected get currentPageDescriptor(): PageDescriptorV4 {
29
+ if (!this.pageId) {
30
+ throw new Error('pageId is not defined');
31
+ }
32
+ if (!this.routePattern) {
33
+ throw new Error('routePattern is not defined');
34
+ }
35
+ if (!this.appComponent) {
36
+ throw new Error('appComponent is not defined');
37
+ }
38
+ return {
39
+ appType: 'fe-v4',
40
+ appComponent: this.appComponent,
41
+ pageId: this.pageId,
42
+ routePattern: this.routePattern
43
+ };
44
+ }
45
+
46
+ protected getApplicationPages(): ApplicationPageData[] {
47
+ return getV4ApplicationPages(this.context.manifest);
48
+ }
49
+
50
+ private async resolveContextPathTargetName(
51
+ contextPath: string,
52
+ metaModel: ODataMetaModelV4
53
+ ): Promise<string | undefined> {
54
+ let result: string | undefined;
55
+ const segments = contextPath.split('/').filter((s) => !!s);
56
+ if (segments.length === 1) {
57
+ // one segment - assumed it is the direct name of entitySet
58
+ result = segments[0];
59
+ } else {
60
+ // resolve segment by segment
61
+ let targetObject = (await metaModel.requestObject(`/${segments[0]}`)) as
62
+ | {
63
+ $Type: string;
64
+ $NavigationPropertyBinding: { [key: string]: string };
65
+ }
66
+ | undefined; // NO SONAR;
67
+
68
+ let idx = 1;
69
+ let targetSetName = '';
70
+ while (targetObject && idx < segments.length) {
71
+ const navProp = segments[idx];
72
+ targetSetName = targetObject.$NavigationPropertyBinding[navProp];
73
+ if (!targetSetName) {
74
+ targetObject = undefined;
75
+ } else {
76
+ targetObject = (await metaModel.requestObject(`/${targetSetName}`)) as
77
+ | {
78
+ $Type: string;
79
+ $NavigationPropertyBinding: { [key: string]: string };
80
+ }
81
+ | undefined; // NO SONAR;
82
+ idx++;
83
+ }
84
+ }
85
+ if (targetObject) {
86
+ result = targetSetName;
87
+ }
88
+ }
89
+ return result;
90
+ }
91
+
92
+ protected async isPageExists(targetEntitySet: string, metaModel: ODataMetaModelV4): Promise<boolean> {
93
+ let pageFound = false;
94
+ let entitySetName: string | undefined;
95
+ for (const page of this.existingPages) {
96
+ if (page.contextPath) {
97
+ // resolve contextPath to target entitySet
98
+ entitySetName = await this.resolveContextPathTargetName(page.contextPath, metaModel);
99
+ } else {
100
+ entitySetName = page.entitySet;
101
+ }
102
+
103
+ if (entitySetName === targetEntitySet) {
104
+ pageFound = true;
105
+ break;
106
+ }
107
+ }
108
+
109
+ return pageFound;
110
+ }
111
+
112
+ protected isCurrentObjectPage(): boolean {
113
+ return this.pageType === OBJECT_PAGE_COMPONENT_NAME_V4;
114
+ }
115
+
116
+ protected getODataMetaModel(): ODataMetaModelV4 | undefined {
117
+ return (this.context.rta.getRootControlInstance().getModel() as ODataModelV4)?.getMetaModel();
118
+ }
119
+
120
+ protected getEntitySetNameFromPageComponent(component: Component | undefined): string {
121
+ if (
122
+ !isA<FEObjectPageComponent>('sap.fe.templates.ListReport.Component', component) &&
123
+ !isA<FEListReportComponent>('sap.fe.templates.ObjectPage.Component', component)
124
+ ) {
125
+ throw new Error('Unexpected type of page owner component');
126
+ }
127
+ return component.getEntitySet();
128
+ }
129
+
130
+ protected async prepareNavigationData(entitySetName: string, metaModel: ODataMetaModelV4) {
131
+ const entitySet = (await metaModel.requestObject(`/${entitySetName}`)) as {
132
+ $Type: string;
133
+ $NavigationPropertyBinding: { [key: string]: string };
134
+ }; // NO SONAR;
135
+ const entityTypePath = entitySet.$Type;
136
+ const entitySetNavigationKeys = Object.keys(entitySet.$NavigationPropertyBinding);
137
+
138
+ for (const navigationProperty of entitySetNavigationKeys) {
139
+ const associationEnd = (await metaModel.requestObject(`/${entityTypePath}/${navigationProperty}`)) as {
140
+ $Type: string;
141
+ $isCollection: boolean;
142
+ $kind: 'NavigationProperty';
143
+ };
144
+ if (associationEnd?.$isCollection) {
145
+ const targetEntitySet = entitySet.$NavigationPropertyBinding[navigationProperty];
146
+ await this.addNavigationOptionIfAvailable(metaModel, targetEntitySet, navigationProperty);
147
+ }
148
+ }
149
+ }
150
+
151
+ async initialize(): Promise<void> {
152
+ const version = await getUi5Version();
153
+ if (isLowerThanMinimalUi5Version(version, { major: 1, minor: 135 })) {
154
+ return;
155
+ }
156
+ await super.initialize();
157
+
158
+ this.appComponent = getV4AppComponent(this.context.view);
159
+
160
+ this.pageId = (this.context.view.getViewData() as ViewDataType)?.stableId.split('::').pop() as string;
161
+ // remember current page route pattern (used in dialog controller for new page change)
162
+ const currentPageRoute = (this.context.manifest['sap.ui5'].routing?.routes ?? []).find(
163
+ (r) => r.name === this.pageId
164
+ );
165
+ if (!currentPageRoute) {
166
+ throw new Error('Current page navigation route not found in manifest');
167
+ }
168
+ this.routePattern = currentPageRoute.pattern;
169
+ }
170
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- sap.ui.define(["../../../cpe/quick-actions/registry", "../common/add-controller-to-page", "./lr-toggle-clear-filter-bar", "./change-table-columns", "../common/op-add-header-field", "../common/op-add-custom-section", "./create-table-custom-column", "../common/create-page-action", "./create-table-action", "./lr-enable-table-filtering", "./lr-enable-semantic-date-range-filter-bar", "./op-enable-empty-row-mode", "../common/add-new-annotation-file", "./enable-variant-management"], function (_____cpe_quick_actions_registry, ___common_add_controller_to_page, ___lr_toggle_clear_filter_bar, ___change_table_columns, ___common_op_add_header_field, ___common_op_add_custom_section, ___create_table_custom_column, ___common_create_page_action, ___create_table_action, ___lr_enable_table_filtering, ___lr_enable_semantic_date_range_filter_bar, ___op_enable_empty_row_mode, ___common_add_new_annotation_file, ___enable_variant_management) {
3
+ sap.ui.define(["../../../cpe/quick-actions/registry", "../common/add-controller-to-page", "./lr-toggle-clear-filter-bar", "./change-table-columns", "../common/op-add-header-field", "../common/op-add-custom-section", "./create-table-custom-column", "../common/create-page-action", "./create-table-action", "./lr-enable-table-filtering", "./lr-enable-semantic-date-range-filter-bar", "./op-enable-empty-row-mode", "../common/add-new-annotation-file", "./enable-variant-management", "../fe-v4/add-new-subpage"], function (_____cpe_quick_actions_registry, ___common_add_controller_to_page, ___lr_toggle_clear_filter_bar, ___change_table_columns, ___common_op_add_header_field, ___common_op_add_custom_section, ___create_table_custom_column, ___common_create_page_action, ___create_table_action, ___lr_enable_table_filtering, ___lr_enable_semantic_date_range_filter_bar, ___op_enable_empty_row_mode, ___common_add_new_annotation_file, ___enable_variant_management, ___fe_v4_add_new_subpage) {
4
4
  "use strict";
5
5
 
6
6
  const QuickActionDefinitionRegistry = _____cpe_quick_actions_registry["QuickActionDefinitionRegistry"];
@@ -17,6 +17,7 @@ sap.ui.define(["../../../cpe/quick-actions/registry", "../common/add-controller-
17
17
  const EnableTableEmptyRowModeQuickAction = ___op_enable_empty_row_mode["EnableTableEmptyRowModeQuickAction"];
18
18
  const AddNewAnnotationFile = ___common_add_new_annotation_file["AddNewAnnotationFile"];
19
19
  const EnableVariantManagementQuickAction = ___enable_variant_management["EnableVariantManagementQuickAction"];
20
+ const AddNewSubpage = ___fe_v4_add_new_subpage["AddNewSubpage"];
20
21
  const LIST_REPORT_TYPE = 'sap.fe.templates.ListReport.ListReport';
21
22
  const OBJECT_PAGE_TYPE = 'sap.fe.templates.ObjectPage.ObjectPage';
22
23
 
@@ -39,14 +40,14 @@ sap.ui.define(["../../../cpe/quick-actions/registry", "../common/add-controller-
39
40
  if (name === 'listReport') {
40
41
  definitionGroups.push({
41
42
  title: 'LIST REPORT',
42
- definitions: [AddControllerToPageQuickAction, AddPageActionQuickAction, ToggleClearFilterBarQuickAction, ToggleSemanticDateRangeFilterBar, EnableVariantManagementQuickAction, ChangeTableColumnsQuickAction, AddTableActionQuickAction, AddTableCustomColumnQuickAction, EnableTableFilteringQuickAction, AddNewAnnotationFile],
43
+ definitions: [AddControllerToPageQuickAction, AddPageActionQuickAction, ToggleClearFilterBarQuickAction, ToggleSemanticDateRangeFilterBar, EnableVariantManagementQuickAction, ChangeTableColumnsQuickAction, AddTableActionQuickAction, AddTableCustomColumnQuickAction, EnableTableFilteringQuickAction, AddNewAnnotationFile, AddNewSubpage],
43
44
  view,
44
45
  key: name + index
45
46
  });
46
47
  } else if (name === 'objectPage') {
47
48
  definitionGroups.push({
48
49
  title: 'OBJECT PAGE',
49
- definitions: [AddControllerToPageQuickAction, AddPageActionQuickAction, AddHeaderFieldQuickAction, AddCustomSectionQuickAction, ChangeTableColumnsQuickAction, EnableVariantManagementQuickAction, AddTableActionQuickAction, AddTableCustomColumnQuickAction, EnableTableEmptyRowModeQuickAction, AddNewAnnotationFile],
50
+ definitions: [AddControllerToPageQuickAction, AddPageActionQuickAction, AddHeaderFieldQuickAction, AddCustomSectionQuickAction, ChangeTableColumnsQuickAction, EnableVariantManagementQuickAction, AddTableActionQuickAction, AddTableCustomColumnQuickAction, EnableTableEmptyRowModeQuickAction, AddNewAnnotationFile, AddNewSubpage],
50
51
  view,
51
52
  key: name + index
52
53
  });
@@ -17,6 +17,7 @@ import { ToggleSemanticDateRangeFilterBar } from './lr-enable-semantic-date-rang
17
17
  import { EnableTableEmptyRowModeQuickAction } from './op-enable-empty-row-mode';
18
18
  import { AddNewAnnotationFile } from '../common/add-new-annotation-file';
19
19
  import { EnableVariantManagementQuickAction } from './enable-variant-management';
20
+ import { AddNewSubpage } from '../fe-v4/add-new-subpage';
20
21
 
21
22
  type PageName = 'listReport' | 'objectPage';
22
23
 
@@ -50,7 +51,8 @@ export default class FEV4QuickActionRegistry extends QuickActionDefinitionRegist
50
51
  AddTableActionQuickAction,
51
52
  AddTableCustomColumnQuickAction,
52
53
  EnableTableFilteringQuickAction,
53
- AddNewAnnotationFile
54
+ AddNewAnnotationFile,
55
+ AddNewSubpage
54
56
  ],
55
57
  view,
56
58
  key: name + index
@@ -68,7 +70,8 @@ export default class FEV4QuickActionRegistry extends QuickActionDefinitionRegist
68
70
  AddTableActionQuickAction,
69
71
  AddTableCustomColumnQuickAction,
70
72
  EnableTableEmptyRowModeQuickAction,
71
- AddNewAnnotationFile
73
+ AddNewAnnotationFile,
74
+ AddNewSubpage
72
75
  ],
73
76
  view,
74
77
  key: name + index
@@ -40,10 +40,35 @@ sap.ui.define(["../../../utils/core", "sap/ui/rta/command/CommandFactory", "../.
40
40
  }
41
41
  return [];
42
42
  }
43
+ const PATTERN_SUFFIX = ':?query:';
44
+
45
+ /**
46
+ * Generates the pattern for a new route based on the input.
47
+ *
48
+ * @param sourceRoutePattern source page route pattern
49
+ * @param navProperty navigation property name (used to build nav pattern for nested OP )
50
+ * @param targetEntitySet navigation target entity set
51
+ * @returns the generated pattern as string
52
+ */
53
+ function generateRoutePattern(sourceRoutePattern, navProperty, targetEntitySet) {
54
+ const parts = [];
55
+ const basePattern = sourceRoutePattern.replace(PATTERN_SUFFIX, '');
56
+ if (basePattern) {
57
+ parts.push(basePattern);
58
+ parts.push('/');
59
+ parts.push(navProperty);
60
+ } else {
61
+ parts.push(targetEntitySet);
62
+ }
63
+ parts.push(`({${targetEntitySet}Key})`);
64
+ parts.push(PATTERN_SUFFIX);
65
+ return parts.join('');
66
+ }
43
67
  var __exports = {
44
68
  __esModule: true
45
69
  };
46
70
  __exports.executeToggleAction = executeToggleAction;
71
+ __exports.generateRoutePattern = generateRoutePattern;
47
72
  return __exports;
48
73
  });
49
74
  //# sourceMappingURL=utils.js.map
@@ -51,3 +51,32 @@ export async function executeToggleAction(
51
51
 
52
52
  return [];
53
53
  }
54
+
55
+ const PATTERN_SUFFIX = ':?query:';
56
+
57
+ /**
58
+ * Generates the pattern for a new route based on the input.
59
+ *
60
+ * @param sourceRoutePattern source page route pattern
61
+ * @param navProperty navigation property name (used to build nav pattern for nested OP )
62
+ * @param targetEntitySet navigation target entity set
63
+ * @returns the generated pattern as string
64
+ */
65
+ export function generateRoutePattern(
66
+ sourceRoutePattern: string,
67
+ navProperty: string,
68
+ targetEntitySet: string
69
+ ): string {
70
+ const parts: string[] = [];
71
+ const basePattern = sourceRoutePattern.replace(PATTERN_SUFFIX, '');
72
+ if (basePattern) {
73
+ parts.push(basePattern);
74
+ parts.push('/');
75
+ parts.push(navProperty);
76
+ } else {
77
+ parts.push(targetEntitySet);
78
+ }
79
+ parts.push(`({${targetEntitySet}Key})`);
80
+ parts.push(PATTERN_SUFFIX);
81
+ return parts.join('');
82
+ }
@@ -1,39 +1,40 @@
1
1
  # Supported UI5 Versions for Quick Actions in Adaptation Projects Based on Fiori Elements Applications with OData V2 and OData V4
2
2
 
3
+ | Quick Action | OData Version | Page Type** | 1.71| 1.84| 1.96|1.108|1.120|1.124|1.127|1.130|1.131|>=1.132.0|>=1.135.0|
4
+ |----------------------------------------------------|---------------|-------------|-----|-----|-----|-----|-----|-----|-----|-----|-----|---------|---------|
5
+ | Add Controller to Page | V2 | LR, ALP, OP | x | x | x | x | x | x | x | x | x | x | x |
6
+ | | V4 | LR, ALP, OP | x | x | x | x | x | x | x | x | x | x | x |
7
+ | Add Header Field | V2 | OP | x | x | x | x | x | x | x | x | x | x | x |
8
+ | | V4 | OP | x | x | x | x | x | x | x | x | x | x | x |
9
+ | Add Custom Section | V2 | OP | x | x | x | x | x | x | x | x | x | x | x |
10
+ | | V4 | OP | x | x | x | x | x | x | x | x | x | x | x |
11
+ | Add Custom Page Action | V2 | LR, ALP, OP | | | | | | | | x | x | x | x |
12
+ | | V4 | LR, ALP, OP | | | | | | | | x | x | x | x |
13
+ | Add Custom Table Action | V2 | LR, ALP, OP | | | x | x | x | x | x | x | x | x | x |
14
+ | | V4 | LR, ALP, OP | | | x | x | x | x | x | x | x | x | x |
15
+ | Add Custom Table Column | V2 | LR, ALP, OP | | | x | x | x | x | x | x | x | x | x |
16
+ | | V4 | LR, ALP, OP | | | x | x | x | x | x | x | x | x | x |
17
+ | Change Table Columns | V2 | LR, ALP, OP | | | x | x | x | x | x | x | x | x | x |
18
+ | | V4 | LR, ALP, OP | | | x | x | x | x | x | x | x | x | x |
19
+ | Enable/Disable "Clear" Button | V2 | LR, ALP | x | x | x | x | x | x | x | x | x | x | x |
20
+ | | V4 | LR, ALP | x | x | x | x | x | x | x | x | x | x | x |
21
+ | Enable Semantic Date Range* | V2 | LR, ALP | | | x | x | x | | | x | x | x | x |
22
+ | | V4 | LR, ALP | | | | | | | | x | x | x | x |
23
+ | Enable Table Filtering for Page Variants* | V2 | LR, ALP | | | x | x | x | | | x | x | x | x |
24
+ | | V4 | LR, ALP | | | | | | | | | x | x | x |
25
+ | Add Local Annotation File* | V2 | LR, ALP, OP | | | | | | | | | | x | x |
26
+ | | V4 | LR, ALP, OP | | | | | | | | | | x | x |
27
+ | Enable Empty Row Mode for Tables* | V2 | OP | | | | | | | | x | x | x | x |
28
+ | | V4 | OP | | | | | | | | | x | x | x |
29
+ | Enable Variant Management in Tables and Charts* | V2 | LR, ALP | | | x | x | x | | | x | x | x | x |
30
+ | | V4 | LR, ALP, OP | | | | | | | | | x | x | x |
31
+ | Enable Variant Management in Tables* | V2 | OP | | | x | x | x | | | x | x | x | x |
32
+ | | V4 | | | | | | | | | | | | |
33
+ | Add Subpage* | V2 | LR, ALP, OP | | | x | x | x | | | x | x | x | x |
34
+ | | V4 | LR, ALP, OP | | | | | | | | | | | x |
3
35
 
4
36
 
5
- Here’s the updated table with the additional column titled ">= SAPUI5 1.132.0":
37
+ *Actions resulting in manifest changes are not available for adaptation projects built for OData v2 applications using outdated array page structure in manifest.json.
6
38
 
7
- | Quick Action | OData Version | Page Type | SAPUI5 1.71 | SAPUI5 1.84 | SAPUI5 1.96 | SAPUI5 1.108 | SAPUI5 1.120 | SAPUI5 1.24 | SAPUI5 1.27 | SAPUI5 1.130 | SAPUI5 1.131 | >= SAPUI5 1.132.0 |
8
- | ---------------------------------------- | ------------- | --------------------------------------- | ----------- | ----------- | ----------- | ------------ | ------------ | ----------- | ----------- | ------------ | ------------ | ---------------- |
9
- | Add Controller to Page | OData V2 | List Report/Analytical List Page, Object Page | X | X | X | X | X | X | X | X | X | X |
10
- | | OData V4 | List Report/Analytical List Page, Object Page | X | X | X | X | X | X | X | X | X | X |
11
- | Add Header Field | OData V2 | Object Page | X | X | X | X | X | X | X | X | X | X |
12
- | | OData V4 | Object Page | X | X | X | X | X | X | X | X | X | X |
13
- | Add Custom Section | OData V2 | Object Page | X | X | X | X | X | X | X | X | X | X |
14
- | | OData V4 | Object Page | X | X | X | X | X | X | X | X | X | X |
15
- | Add Custom Page Action | OData V2 | List Report/Analytical List Page, Object Page | | | | | | | | X | X | X |
16
- | | OData V4 | List Report/Analytical List Page, Object Page | | | | | | | | X | X | X |
17
- | Add Custom Table Action | OData V2 | List Report/Analytical List Page, Object Page | | | X | X | X | X | X | X | X | X |
18
- | | OData V4 | List Report/Analytical List Page, Object Page | | | X | X | X | X | X | X | X | X |
19
- | Add Custom Table Column | OData V2 | List Report/Analytical List Page, Object Page | | | X | X | X | X | X | X | X | X |
20
- | | OData V4 | List Report/Analytical List Page, Object Page | | | X | X | X | X | X | X | X | X |
21
- | Change Table Columns | OData V2 | List Report/Analytical List Page, Object Page | | | X | X | X | X | X | X | X | X |
22
- | | OData V4 | List Report/Analytical List Page, Object Page | | | X | X | X | X | X | X | X | X |
23
- | Enable/Disable "Clear" Button | OData V2 | List Report/Analytical List Page | X | X | X | X | X | X | X | X | X | X |
24
- | | OData V4 | List Report/Analytical List Page | X | X | X | X | X | X | X | X | X | X |
25
- | Enable Semantic Date Range* | OData V2 | List Report/Analytical List Page | | | X | X | X | | | X | X | X |
26
- | | OData V4 | List Report/Analytical List Page | | | | | | | | X | X | X |
27
- | Enable Table Filtering for Page Variants*| OData V2 | List Report/Analytical List Page | | | X | X | X | | | X | X | X |
28
- | | OData V4 | List Report/Analytical List Page | | | | | | | | | X | X |
29
- | Add Local Annotation File* | OData V2 | List Report/Analytical List Page, Object Page | | | | | | | | | | X |
30
- | | OData V4 | List Report/Analytical List Page, Object Page | | | | | | | | | | X |
31
- | Enable Empty Row Mode for Tables* | OData V2 | Object Page | | | | | | | | X | X | X |
32
- | | OData V4 | Object Page | | | | | | | | | X | X |
33
- | Enable Variant Management in Tables and Charts* | OData V2 | List Report/Analytical List Page | | | X | X | X | | | X | X | X |
34
- | | OData V4 | List Report/Analytical List Page, Object Page | | | | | | | | | X | X |
35
- | Enable Variant Management in Tables* | OData V2 | Object Page | | | X | X | X | | | X | X | X |
36
- | |
37
-
38
- *Actions resulting in manifest changes are not available for adaptation projects built for OData v2 appliactions using outdated array page structure in manifest.json.
39
+ ** Meaning of Page Type abbreviation: LR - List Report, ALP - Analytical List Page, OP - Object Page
39
40
 
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- sap.ui.define(["sap/m/MessageToast", "sap/ui/core/Element", "sap/base/Log", "sap/ui/fl/Utils", "../utils/error", "../utils/version"], function (MessageToast, Element, Log, FlexUtils, ___utils_error, ___utils_version) {
3
+ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/Element", "sap/base/Log", "sap/ui/fl/Utils", "../utils/core", "../utils/error", "../utils/version"], function (MessageToast, Element, Log, FlexUtils, ___utils_core, ___utils_error, ___utils_version) {
4
4
  "use strict";
5
5
 
6
6
  function __ui5_require_async(path) {
@@ -20,8 +20,18 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/Element", "sap/base/Log", "sap
20
20
  });
21
21
  });
22
22
  }
23
+ const getControlById = ___utils_core["getControlById"];
23
24
  const getError = ___utils_error["getError"];
24
25
  const isLowerThanMinimalUi5Version = ___utils_version["isLowerThanMinimalUi5Version"];
26
+ let reuseComponentChecker;
27
+
28
+ /**
29
+ * Resets the reuse component checker.
30
+ */
31
+ function resetReuseComponentChecker() {
32
+ reuseComponentChecker = undefined;
33
+ }
34
+
25
35
  /**
26
36
  * Defers the resolution of the promise, stores resolve/reject functions so that they can be accessed at a later stage.
27
37
  *
@@ -148,15 +158,63 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/Element", "sap/base/Log", "sap
148
158
  const control = overlayControl.getElement();
149
159
  return getControllerInfoForControl(control);
150
160
  }
161
+
162
+ /**
163
+ * Gets the reuse component checker function.
164
+ *
165
+ * @param ui5VersionInfo UI5 version information.
166
+ * @returns The reuse component checker function.
167
+ */
168
+ async function getReuseComponentChecker(ui5VersionInfo) {
169
+ if (reuseComponentChecker) {
170
+ return reuseComponentChecker;
171
+ }
172
+ let reuseComponentApi;
173
+ if (!isLowerThanMinimalUi5Version(ui5VersionInfo, {
174
+ major: 1,
175
+ minor: 134
176
+ })) {
177
+ reuseComponentApi = (await __ui5_require_async('sap/ui/rta/util/isReuseComponent')).default;
178
+ }
179
+ reuseComponentChecker = function isReuseComponent(controlId) {
180
+ const ui5Control = getControlById(controlId);
181
+ if (!ui5Control) {
182
+ return false;
183
+ }
184
+ const component = FlexUtils.getComponentForControl(ui5Control);
185
+ if (reuseComponentApi) {
186
+ return reuseComponentApi.isReuseComponent(component);
187
+ }
188
+ if (!component) {
189
+ return false;
190
+ }
191
+ const appComponent = FlexUtils.getAppComponentForControl(component);
192
+ if (!appComponent) {
193
+ return false;
194
+ }
195
+ const manifest = component.getManifest();
196
+ const appManifest = appComponent.getManifest();
197
+ const componentName = manifest?.['sap.app']?.id;
198
+
199
+ // Look for component name in component usages of app component manifest
200
+ const componentUsages = appManifest?.['sap.ui5']?.componentUsages;
201
+ return Object.values(componentUsages || {}).some(componentUsage => {
202
+ return componentUsage.name === componentName;
203
+ });
204
+ };
205
+ return reuseComponentChecker;
206
+ }
151
207
  var __exports = {
152
208
  __esModule: true
153
209
  };
210
+ __exports.resetReuseComponentChecker = resetReuseComponentChecker;
154
211
  __exports.createDeferred = createDeferred;
155
212
  __exports.matchesFragmentName = matchesFragmentName;
156
213
  __exports.notifyUser = notifyUser;
157
214
  __exports.getAllSyncViewsIds = getAllSyncViewsIds;
158
215
  __exports.getControllerInfoForControl = getControllerInfoForControl;
159
216
  __exports.getControllerInfo = getControllerInfo;
217
+ __exports.getReuseComponentChecker = getReuseComponentChecker;
160
218
  return __exports;
161
219
  });
162
220
  //# sourceMappingURL=utils.js.map
@@ -6,6 +6,9 @@ import type ManagedObject from 'sap/ui/base/ManagedObject';
6
6
  import type ElementOverlay from 'sap/ui/dt/ElementOverlay';
7
7
  import Log from 'sap/base/Log';
8
8
  import FlexUtils from 'sap/ui/fl/Utils';
9
+ import IsReuseComponentApi from 'sap/ui/rta/util/isReuseComponent';
10
+ import { getControlById } from '../utils/core';
11
+ import type { Manifest } from 'sap/ui/rta/RuntimeAuthoring';
9
12
 
10
13
  import { getError } from '../utils/error';
11
14
  import { isLowerThanMinimalUi5Version, Ui5VersionInfo } from '../utils/version';
@@ -22,6 +25,17 @@ export interface FragmentChange {
22
25
  };
23
26
  }
24
27
 
28
+ export type ReuseComponentChecker = (controlId: string) => boolean;
29
+
30
+ let reuseComponentChecker: ReuseComponentChecker | undefined;
31
+
32
+ /**
33
+ * Resets the reuse component checker.
34
+ */
35
+ export function resetReuseComponentChecker(): void {
36
+ reuseComponentChecker = undefined;
37
+ }
38
+
25
39
  /**
26
40
  * Defers the resolution of the promise, stores resolve/reject functions so that they can be accessed at a later stage.
27
41
  *
@@ -146,3 +160,54 @@ export function getControllerInfo(overlayControl: ElementOverlay): ControllerInf
146
160
  const control = overlayControl.getElement();
147
161
  return getControllerInfoForControl(control);
148
162
  }
163
+
164
+ /**
165
+ * Gets the reuse component checker function.
166
+ *
167
+ * @param ui5VersionInfo UI5 version information.
168
+ * @returns The reuse component checker function.
169
+ */
170
+ export async function getReuseComponentChecker(ui5VersionInfo: Ui5VersionInfo): Promise<ReuseComponentChecker> {
171
+ if (reuseComponentChecker) {
172
+ return reuseComponentChecker;
173
+ }
174
+
175
+ let reuseComponentApi: IsReuseComponentApi;
176
+ if (!isLowerThanMinimalUi5Version(ui5VersionInfo, { major: 1, minor: 134 })) {
177
+ reuseComponentApi = (await import('sap/ui/rta/util/isReuseComponent')).default;
178
+ }
179
+
180
+ reuseComponentChecker = function isReuseComponent(controlId: string): boolean {
181
+ const ui5Control = getControlById(controlId);
182
+ if (!ui5Control) {
183
+ return false;
184
+ }
185
+
186
+ const component = FlexUtils.getComponentForControl(ui5Control);
187
+
188
+ if (reuseComponentApi) {
189
+ return reuseComponentApi.isReuseComponent(component);
190
+ }
191
+
192
+ if (!component) {
193
+ return false;
194
+ }
195
+
196
+ const appComponent = FlexUtils.getAppComponentForControl(component);
197
+ if (!appComponent) {
198
+ return false;
199
+ }
200
+
201
+ const manifest = component.getManifest() as Manifest;
202
+ const appManifest = appComponent.getManifest() as Manifest;
203
+ const componentName = manifest?.['sap.app']?.id;
204
+
205
+ // Look for component name in component usages of app component manifest
206
+ const componentUsages = appManifest?.['sap.ui5']?.componentUsages;
207
+ return Object.values(componentUsages || {}).some((componentUsage) => {
208
+ return componentUsage.name === componentName;
209
+ });
210
+ };
211
+
212
+ return reuseComponentChecker;
213
+ }
@@ -1,13 +1,11 @@
1
1
  "use strict";
2
2
 
3
- sap.ui.define(["sap/base/Log", "../../utils/version", "../../utils/core", "../../utils/error", "../utils", "./editable", "../../utils/fe-v4"], function (Log, ____utils_version, ____utils_core, ____utils_error, ___utils, ___editable, ____utils_fe_v4) {
3
+ sap.ui.define(["sap/base/Log", "../../utils/core", "../../utils/error", "../utils", "./editable", "../../utils/fe-v4"], function (Log, ____utils_core, ____utils_error, ___utils, ___editable, ____utils_fe_v4) {
4
4
  "use strict";
5
5
 
6
- const getUi5Version = ____utils_version["getUi5Version"];
7
6
  const getControlById = ____utils_core["getControlById"];
8
7
  const getError = ____utils_error["getError"];
9
8
  const getOverlay = ___utils["getOverlay"];
10
- const isReuseComponent = ___utils["isReuseComponent"];
11
9
  const isEditable = ___editable["isEditable"];
12
10
  const getConfigMapControlIdMap = ____utils_fe_v4["getConfigMapControlIdMap"];
13
11
  const getPageName = ____utils_fe_v4["getPageName"];
@@ -111,16 +109,14 @@ sap.ui.define(["sap/base/Log", "../../utils/version", "../../utils/core", "../..
111
109
  *
112
110
  * @param input outline view node
113
111
  * @param scenario type of project
114
- * @param reuseComponentsIds ids of reuse components that are filled when outline nodes are transformed
115
112
  * @param controlIndex Control tree index
116
113
  * @param changeService ChangeService for change stack event handling.
117
114
  * @param propertyIdMap ChangeService for change stack event handling.
118
115
  * @returns transformed outline tree nodes
119
116
  */
120
- async function transformNodes(input, scenario, reuseComponentsIds, controlIndex, changeService, propertyIdMap) {
117
+ async function transformNodes(input, scenario, controlIndex, changeService, propertyIdMap) {
121
118
  const stack = [...input];
122
119
  const items = [];
123
- const ui5VersionInfo = await getUi5Version();
124
120
  while (stack.length) {
125
121
  try {
126
122
  const current = stack.shift();
@@ -133,7 +129,7 @@ sap.ui.define(["sap/base/Log", "../../utils/version", "../../utils/core", "../..
133
129
  text
134
130
  } = getAdditionalData(current.id);
135
131
  const technicalName = current.technicalName.split('.').slice(-1)[0];
136
- const transformedChildren = isAdp ? await handleDuplicateNodes(children, scenario, reuseComponentsIds, controlIndex, changeService, propertyIdMap) : await transformNodes(children, scenario, reuseComponentsIds, controlIndex, changeService, propertyIdMap);
132
+ const transformedChildren = isAdp ? await handleDuplicateNodes(children, scenario, controlIndex, changeService, propertyIdMap) : await transformNodes(children, scenario, controlIndex, changeService, propertyIdMap);
137
133
  const node = {
138
134
  controlId: current.id,
139
135
  controlType: current.technicalName,
@@ -144,7 +140,6 @@ sap.ui.define(["sap/base/Log", "../../utils/version", "../../utils/core", "../..
144
140
  };
145
141
  indexNode(controlIndex, node);
146
142
  addToPropertyIdMap(node, propertyIdMap);
147
- fillReuseComponents(reuseComponentsIds, current, scenario, ui5VersionInfo);
148
143
  items.push(node);
149
144
  }
150
145
  if (isAdp && isExtPoint) {
@@ -175,32 +170,18 @@ sap.ui.define(["sap/base/Log", "../../utils/version", "../../utils/core", "../..
175
170
  return items;
176
171
  }
177
172
 
178
- /**
179
- * Fill reuse components ids.
180
- *
181
- * @param reuseComponentsIds ids of reuse components that are filled when outline nodes are transformed
182
- * @param node view node
183
- * @param scenario type of project
184
- * @param ui5VersionInfo UI5 version information
185
- */
186
- function fillReuseComponents(reuseComponentsIds, node, scenario, ui5VersionInfo) {
187
- if (scenario === 'ADAPTATION_PROJECT' && node?.component && isReuseComponent(node.id, ui5VersionInfo)) {
188
- reuseComponentsIds.add(node.id);
189
- }
190
- }
191
173
  /**
192
174
  * Handles duplicate nodes that are retrieved from extension point default content and created controls,
193
175
  * if they exist under an extension point these controls are removed from the children array
194
176
  *
195
177
  * @param children outline view node children
196
178
  * @param scenario type of project
197
- * @param reuseComponentsIds ids of reuse components that are filled when outline nodes are transformed
198
179
  * @param controlIndex Control tree index
199
180
  * @param changeService ChangeService for change stack event handling.
200
181
  * @param propertyIdMap Map<string, string[]>.
201
182
  * @returns transformed outline tree nodes
202
183
  */
203
- async function handleDuplicateNodes(children, scenario, reuseComponentsIds, controlIndex, changeService, propertyIdMap) {
184
+ async function handleDuplicateNodes(children, scenario, controlIndex, changeService, propertyIdMap) {
204
185
  const extPointIDs = new Set();
205
186
  children.forEach(child => {
206
187
  if (child.type === 'extensionPoint') {
@@ -212,7 +193,7 @@ sap.ui.define(["sap/base/Log", "../../utils/version", "../../utils/core", "../..
212
193
  }
213
194
  });
214
195
  const uniqueChildren = children.filter(child => !extPointIDs.has(child.id));
215
- return transformNodes(uniqueChildren, scenario, reuseComponentsIds, controlIndex, changeService, propertyIdMap);
196
+ return transformNodes(uniqueChildren, scenario, controlIndex, changeService, propertyIdMap);
216
197
  }
217
198
  var __exports = {
218
199
  __esModule: true