@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
@@ -6,8 +6,9 @@ sap.ui.define([
6
6
  './BaseDialog.controller',
7
7
  'sap/ui/rta/command/CommandFactory',
8
8
  '../../cpe/communication-service',
9
- 'open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common'
10
- ], function (JSONModel, ____i18n, __CommandExecutor, __BaseDialog, CommandFactory, ____cpe_communication_service, ___sap_ux_private_control_property_editor_common) {
9
+ 'open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common',
10
+ '../quick-actions/fe-v4/utils'
11
+ ], function (JSONModel, ____i18n, __CommandExecutor, __BaseDialog, CommandFactory, ____cpe_communication_service, ___sap_ux_private_control_property_editor_common, ___quick_actions_fe_v4_utils) {
11
12
  'use strict';
12
13
  function _interopRequireDefault(obj) {
13
14
  return obj && obj.__esModule && typeof obj.default !== 'undefined' ? obj.default : obj;
@@ -17,6 +18,7 @@ sap.ui.define([
17
18
  const BaseDialog = _interopRequireDefault(__BaseDialog);
18
19
  const CommunicationService = ____cpe_communication_service['CommunicationService'];
19
20
  const setApplicationRequiresReload = ___sap_ux_private_control_property_editor_common['setApplicationRequiresReload'];
21
+ const generateRoutePattern = ___quick_actions_fe_v4_utils['generateRoutePattern'];
20
22
  const AddSubpage = BaseDialog.extend('open.ux.preview.client.adp.controllers.AddSubpage', {
21
23
  constructor: function _constructor(name, overlays, rta, options, telemetryData) {
22
24
  BaseDialog.prototype.constructor.call(this, name, telemetryData);
@@ -24,12 +26,8 @@ sap.ui.define([
24
26
  this.rta = rta;
25
27
  this.overlays = overlays;
26
28
  this.model = new JSONModel({
27
- appType: options.appType,
28
- appReference: options.appReference,
29
- pageType: options.pageDescriptor.pageType,
30
29
  title: options.title,
31
- navigationData: options.pageDescriptor.navProperties,
32
- currentEntitySet: options.pageDescriptor.entitySet
30
+ navigationData: options.navProperties
33
31
  });
34
32
  this.commandExecutor = new CommandExecutor(this.rta);
35
33
  },
@@ -57,43 +55,54 @@ sap.ui.define([
57
55
  const navProperty = this.model.getProperty('/selectedNavigation/key');
58
56
  const navigation = this.model.getProperty('/navigationData').find(item => item.navProperty = navProperty);
59
57
  const targetEntitySet = navigation?.entitySet ?? '';
60
- const appType = this.model.getProperty('/appType');
61
- const pageType = this.model.getProperty('/pageType');
62
- const modifiedValue = appType === 'fe-v2' ? {
63
- changeType: 'appdescr_ui_generic_app_addNewObjectPage',
64
- reference: this.model.getProperty('/appReference'),
65
- parameters: {
66
- parentPage: {
67
- component: pageType,
68
- entitySet: this.model.getProperty('/currentEntitySet')
69
- },
70
- childPage: {
71
- id: `ObjectPage|${ navProperty }`,
72
- definition: {
73
- entitySet: targetEntitySet,
74
- navigationProperty: navProperty
58
+ const pageDescriptor = this.options.pageDescriptor;
59
+ let modifiedValue;
60
+ if (pageDescriptor.appType === 'fe-v2') {
61
+ modifiedValue = {
62
+ appComponent: pageDescriptor.appComponent,
63
+ changeType: 'appdescr_ui_generic_app_addNewObjectPage',
64
+ reference: this.options.appReference,
65
+ parameters: {
66
+ parentPage: {
67
+ component: pageDescriptor.pageType,
68
+ entitySet: pageDescriptor.entitySet
69
+ },
70
+ childPage: {
71
+ id: `ObjectPage|${ navProperty }`,
72
+ definition: {
73
+ entitySet: targetEntitySet,
74
+ navigationProperty: navProperty
75
+ }
75
76
  }
76
77
  }
77
- }
78
- } : {
79
- changeType: 'appdescr_fe_addNewPage',
80
- parameters: {
81
- sourcePage: {
82
- id: this.runtimeControl.getId(),
83
- navigationSource: targetEntitySet
84
- },
85
- targetPage: {
86
- type: 'Component',
87
- id: `${ targetEntitySet }ObjectPage`,
88
- name: 'sap.fe.templates.ObjectPage',
89
- routePattern: `${ targetEntitySet }({key}):?query:`,
90
- settings: {
91
- contextPath: `/${ targetEntitySet }`,
92
- editableHeaderContent: false
78
+ };
79
+ } else {
80
+ const routePattern = generateRoutePattern(pageDescriptor.routePattern, navProperty, targetEntitySet);
81
+ modifiedValue = {
82
+ appComponent: pageDescriptor.appComponent,
83
+ changeType: 'appdescr_fe_addNewPage',
84
+ reference: this.options.appReference,
85
+ parameters: {
86
+ sourcePage: {
87
+ id: pageDescriptor.pageId,
88
+ navigationSource: navProperty
89
+ },
90
+ targetPage: {
91
+ type: 'Component',
92
+ id: `${ targetEntitySet }ObjectPage`,
93
+ name: 'sap.fe.templates.ObjectPage',
94
+ routePattern,
95
+ settings: {
96
+ contextPath: `/${ targetEntitySet }`,
97
+ editableHeaderContent: false,
98
+ entitySet: targetEntitySet,
99
+ pageLayout: '',
100
+ controlConfiguration: {}
101
+ }
93
102
  }
94
103
  }
95
- }
96
- };
104
+ };
105
+ }
97
106
  const command = await CommandFactory.getCommandFor(this.runtimeControl, 'appDescriptor', modifiedValue, null, flexSettings);
98
107
  await this.commandExecutor.pushAndExecuteCommand(command);
99
108
  CommunicationService.sendAction(setApplicationRequiresReload(true));
@@ -15,6 +15,12 @@ import JSONModel from 'sap/ui/model/json/JSONModel';
15
15
  /** sap.ui.rta */
16
16
  import type RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
17
17
 
18
+ /** sap.fe.core */
19
+ import type AppComponentV4 from 'sap/fe/core/AppComponent';
20
+
21
+ /** sap.suite.ui.generic */
22
+ import type AppComponentV2 from 'sap/suite/ui/generic/template/lib/AppComponent';
23
+
18
24
  import { getResourceModel } from '../../i18n';
19
25
 
20
26
  import CommandExecutor from '../command-executor';
@@ -22,35 +28,41 @@ import CommandExecutor from '../command-executor';
22
28
  import BaseDialog from './BaseDialog.controller';
23
29
 
24
30
  import CommandFactory from 'sap/ui/rta/command/CommandFactory';
25
- import { ApplicationType } from '../../utils/application';
26
31
  import { CommunicationService } from '../../cpe/communication-service';
27
32
  import { setApplicationRequiresReload } from '@sap-ux-private/control-property-editor-common';
33
+ import { generateRoutePattern } from '../quick-actions/fe-v4/utils';
28
34
  import { QuickActionTelemetryData } from '../../cpe/quick-actions/quick-action-definition';
29
35
 
30
36
  type SubpageType = 'ObjectPage' | 'CustomPage';
31
37
 
38
+ export interface PageDescriptorV2 {
39
+ appType: 'fe-v2';
40
+ appComponent: AppComponentV2;
41
+ entitySet: string;
42
+ pageType: string;
43
+ }
44
+
45
+ export interface PageDescriptorV4 {
46
+ appType: 'fe-v4';
47
+ appComponent: AppComponentV4;
48
+ pageId: string;
49
+ routePattern: string;
50
+ }
51
+
52
+ export interface AddSubpageOptions {
53
+ appReference: string;
54
+ title: string;
55
+ navProperties: { navProperty: string; entitySet: string }[];
56
+ pageDescriptor: PageDescriptorV2 | PageDescriptorV4;
57
+ }
58
+
32
59
  export type AddSubpageModel = JSONModel & {
33
- getProperty(sPath: '/appType'): ApplicationType;
34
- getProperty(sPath: '/pageType'): string;
35
- getProperty(sPath: '/appReference'): string;
36
- getProperty(sPath: '/currentEntitySet'): string;
37
60
  getProperty(sPath: '/title'): string;
38
61
  getProperty(sPath: '/navigationData'): { navProperty: string; entitySet: string }[];
39
62
  getProperty(sPath: '/selectedPageType/key'): SubpageType;
40
63
  getProperty(sPath: '/selectedNavigation/key'): string;
41
64
  };
42
65
 
43
- export interface AddSubpageOptions {
44
- appType: ApplicationType;
45
- appReference: string;
46
- title: string;
47
- pageDescriptor: {
48
- pageType: string;
49
- entitySet: string;
50
- navProperties: { navProperty: string; entitySet: string }[];
51
- };
52
- }
53
-
54
66
  /**
55
67
  * @namespace open.ux.preview.client.adp.controllers
56
68
  */
@@ -66,12 +78,8 @@ export default class AddSubpage extends BaseDialog<AddSubpageModel> {
66
78
  this.rta = rta;
67
79
  this.overlays = overlays;
68
80
  this.model = new JSONModel({
69
- appType: options.appType,
70
- appReference: options.appReference,
71
- pageType: options.pageDescriptor.pageType,
72
81
  title: options.title,
73
- navigationData: options.pageDescriptor.navProperties,
74
- currentEntitySet: options.pageDescriptor.entitySet
82
+ navigationData: options.navProperties
75
83
  });
76
84
  this.commandExecutor = new CommandExecutor(this.rta);
77
85
  }
@@ -119,47 +127,56 @@ export default class AddSubpage extends BaseDialog<AddSubpageModel> {
119
127
  const navProperty = this.model.getProperty('/selectedNavigation/key');
120
128
  const navigation = this.model.getProperty('/navigationData').find((item) => (item.navProperty = navProperty));
121
129
  const targetEntitySet = navigation?.entitySet ?? '';
122
- const appType = this.model.getProperty('/appType');
123
- const pageType = this.model.getProperty('/pageType');
124
-
125
- const modifiedValue =
126
- appType === 'fe-v2'
127
- ? {
128
- changeType: 'appdescr_ui_generic_app_addNewObjectPage',
129
- reference: this.model.getProperty('/appReference'),
130
- parameters: {
131
- parentPage: {
132
- component: pageType,
133
- entitySet: this.model.getProperty('/currentEntitySet')
134
- },
135
- childPage: {
136
- id: `ObjectPage|${navProperty}`,
137
- definition: {
138
- entitySet: targetEntitySet,
139
- navigationProperty: navProperty
140
- }
141
- }
142
- }
143
- }
144
- : {
145
- changeType: 'appdescr_fe_addNewPage',
146
- parameters: {
147
- sourcePage: {
148
- id: this.runtimeControl.getId(),
149
- navigationSource: targetEntitySet
150
- },
151
- targetPage: {
152
- type: 'Component',
153
- id: `${targetEntitySet}ObjectPage`,
154
- name: 'sap.fe.templates.ObjectPage',
155
- routePattern: `${targetEntitySet}({key}):?query:`,
156
- settings: {
157
- contextPath: `/${targetEntitySet}`,
158
- editableHeaderContent: false
159
- }
160
- }
161
- }
162
- };
130
+
131
+ const pageDescriptor = this.options.pageDescriptor;
132
+
133
+ let modifiedValue;
134
+ if (pageDescriptor.appType === 'fe-v2') {
135
+ modifiedValue = {
136
+ appComponent: pageDescriptor.appComponent,
137
+ changeType: 'appdescr_ui_generic_app_addNewObjectPage',
138
+ reference: this.options.appReference,
139
+ parameters: {
140
+ parentPage: {
141
+ component: pageDescriptor.pageType,
142
+ entitySet: pageDescriptor.entitySet
143
+ },
144
+ childPage: {
145
+ id: `ObjectPage|${navProperty}`,
146
+ definition: {
147
+ entitySet: targetEntitySet,
148
+ navigationProperty: navProperty
149
+ }
150
+ }
151
+ }
152
+ };
153
+ } else {
154
+ const routePattern = generateRoutePattern(pageDescriptor.routePattern, navProperty, targetEntitySet);
155
+ modifiedValue = {
156
+ appComponent: pageDescriptor.appComponent,
157
+ changeType: 'appdescr_fe_addNewPage',
158
+ reference: this.options.appReference,
159
+ parameters: {
160
+ sourcePage: {
161
+ id: pageDescriptor.pageId,
162
+ navigationSource: navProperty
163
+ },
164
+ targetPage: {
165
+ type: 'Component',
166
+ id: `${targetEntitySet}ObjectPage`,
167
+ name: 'sap.fe.templates.ObjectPage',
168
+ routePattern,
169
+ settings: {
170
+ contextPath: `/${targetEntitySet}`,
171
+ editableHeaderContent: false,
172
+ entitySet: targetEntitySet,
173
+ pageLayout: '',
174
+ controlConfiguration: {}
175
+ }
176
+ }
177
+ }
178
+ };
179
+ }
163
180
 
164
181
  const command = await CommandFactory.getCommandFor(
165
182
  this.runtimeControl,
@@ -1,26 +1,27 @@
1
1
  "use strict";
2
2
 
3
- sap.ui.define(["sap/ui/rta/util/hasStableId", "sap/ui/fl/Utils", "../cpe/utils", "./dialog-factory"], function (hasStableId, FlUtils, ___cpe_utils, ___dialog_factory) {
3
+ sap.ui.define(["sap/ui/rta/util/hasStableId", "sap/ui/fl/Utils", "./dialog-factory", "../i18n", "./utils"], function (hasStableId, FlUtils, ___dialog_factory, ___i18n, ___utils) {
4
4
  "use strict";
5
5
 
6
- const isReuseComponent = ___cpe_utils["isReuseComponent"];
7
6
  const DialogFactory = ___dialog_factory["DialogFactory"];
8
7
  const DialogNames = ___dialog_factory["DialogNames"];
8
+ const getTextBundle = ___i18n["getTextBundle"];
9
+ const getReuseComponentChecker = ___utils["getReuseComponentChecker"];
9
10
  /**
10
11
  * Handler for enablement of Extend With Controller context menu entry
11
12
  *
12
13
  * @param control UI5 control.
13
14
  * @param syncViewsIds Runtime Authoring
14
- * @param ui5VersionInfo UI5 version information
15
+ * @param isReuseComponent Function to check if the control is a reuse component.
15
16
  * @param isCloud Whether the application is running in the cloud
16
17
  *
17
18
  * @returns boolean whether menu item is enabled or not
18
19
  */
19
- function isControllerExtensionEnabledForControl(control, syncViewsIds, ui5VersionInfo, isCloud) {
20
- const clickedControlId = FlUtils.getViewForControl(control).getId();
21
- const isControlInSyncView = syncViewsIds.includes(clickedControlId);
20
+ function isControllerExtensionEnabledForControl(control, syncViewsIds, isReuseComponent, isCloud) {
21
+ const viewId = FlUtils.getViewForControl(control).getId();
22
+ const isControlInSyncView = syncViewsIds.includes(viewId);
22
23
  if (isCloud) {
23
- const isClickedControlReuseComponent = isReuseComponent(clickedControlId, ui5VersionInfo);
24
+ const isClickedControlReuseComponent = isReuseComponent(control.getId());
24
25
  return !isControlInSyncView && !isClickedControlReuseComponent;
25
26
  }
26
27
  return !isControlInSyncView;
@@ -31,44 +32,71 @@ sap.ui.define(["sap/ui/rta/util/hasStableId", "sap/ui/fl/Utils", "../cpe/utils",
31
32
  *
32
33
  * @param overlays Control overlays
33
34
  * @param syncViewsIds Runtime Authoring
34
- * @param ui5VersionInfo UI5 version information
35
+ * @param isReuseComponent Function to check if the control is a reuse component.
35
36
  * @param isCloud Whether the application is running in the cloud
36
37
  *
37
38
  * @returns boolean whether menu item is enabled or not
38
39
  */
39
- const isControllerExtensionEnabled = (overlays, syncViewsIds, ui5VersionInfo, isCloud) => {
40
+ const isControllerExtensionEnabled = (overlays, syncViewsIds, isReuseComponent, isCloud) => {
40
41
  if (overlays.length === 0 || overlays.length > 1) {
41
42
  return false;
42
43
  }
43
- return isControllerExtensionEnabledForControl(overlays[0].getElement(), syncViewsIds, ui5VersionInfo, isCloud);
44
+ return isControllerExtensionEnabledForControl(overlays[0].getElement(), syncViewsIds, isReuseComponent, isCloud);
44
45
  };
45
46
 
46
47
  /**
47
48
  * Determines whether the fragment command should be enabled based on the provided overlays.
48
49
  *
49
50
  * @param {ElementOverlay[]} overlays - An array of ElementOverlay objects representing the UI overlays.
50
- * @param ui5VersionInfo UI5 version information
51
+ * @param {isReuseComponentApi} isReuseComponent - Function to check if the control is a reuse component.
52
+ * @param {boolean} isCloud - Whether the application is running in the cloud.
51
53
  * @returns {boolean} True if the fragment command is enabled, false otherwise.
52
54
  */
53
- const isFragmentCommandEnabled = (overlays, ui5VersionInfo) => {
55
+ const isFragmentCommandEnabled = (overlays, isReuseComponent, isCloud) => {
54
56
  if (overlays.length === 0 || overlays.length > 1) {
55
57
  return false;
56
58
  }
57
59
  const control = overlays[0].getElement();
58
- return hasStableId(overlays[0]) && !isReuseComponent(control.getId(), ui5VersionInfo);
60
+ const stableId = hasStableId(overlays[0]);
61
+ if (isCloud) {
62
+ return stableId && !isReuseComponent(control.getId());
63
+ }
64
+ return stableId;
59
65
  };
60
66
 
61
67
  /**
62
68
  * Determines the text that should be displayed for the Add Fragment context menu item.
63
69
  *
64
70
  * @param {ElementOverlay} overlay - An ElementOverlay object representing the UI overlay.
71
+ * @param {isReuseComponentApi} isReuseComponentChecker - Function to check if the control is a reuse component.
72
+ * @param {boolean} isCloud - Whether the application is running in the cloud.
73
+ * @param {TextBundle} resources - The text bundle.
65
74
  * @returns {string} The text of the Add Fragment context menu item.
66
75
  */
67
- const getAddFragmentItemText = overlay => {
76
+ const getAddFragmentItemText = (overlay, isReuseComponentChecker, isCloud, resources) => {
77
+ if (isCloud && isReuseComponentChecker(overlay.getElement().getId())) {
78
+ return resources.getText('ADP_ADD_FRAGMENT_MENU_ITEM_REUSE_COMPONENT');
79
+ }
68
80
  if (!hasStableId(overlay)) {
69
- return 'Add: Fragment (Unavailable due to unstable ID of the control or its parent control)';
81
+ return resources.getText('ADP_ADD_FRAGMENT_MENU_ITEM_UNSTABLE_ID');
82
+ }
83
+ return resources.getText('ADP_ADD_FRAGMENT_MENU_ITEM');
84
+ };
85
+
86
+ /**
87
+ * Determines the text that should be displayed for Controller Extension context menu item.
88
+ *
89
+ * @param {ElementOverlay} overlay - An ElementOverlay object representing the UI overlay.
90
+ * @param {isReuseComponentApi} isReuseComponentChecker - Function to check if the control is a reuse component.
91
+ * @param {boolean} isCloud - Whether the application is running in the cloud.
92
+ * @param {TextBundle} resources - The text bundle.
93
+ * @returns {string} The text of the Add Fragment context menu item.
94
+ */
95
+ const getExtendControllerItemText = (overlay, isReuseComponentChecker, isCloud, resources) => {
96
+ if (isCloud && isReuseComponentChecker(overlay.getElement().getId())) {
97
+ return resources.getText('ADP_ADD_CONTROLLER_EXTENSION_MENU_ITEM_REUSE_COMPONENT');
70
98
  }
71
- return 'Add: Fragment';
99
+ return resources.getText('ADP_ADD_CONTROLLER_EXTENSION_MENU_ITEM');
72
100
  };
73
101
 
74
102
  /**
@@ -78,22 +106,24 @@ sap.ui.define(["sap/ui/rta/util/hasStableId", "sap/ui/fl/Utils", "../cpe/utils",
78
106
  * @param syncViewsIds Ids of all application sync views
79
107
  * @param ui5VersionInfo UI5 version information
80
108
  */
81
- const initDialogs = (rta, syncViewsIds, ui5VersionInfo) => {
109
+ const initDialogs = async (rta, syncViewsIds, ui5VersionInfo) => {
82
110
  const contextMenu = rta.getDefaultPlugins().contextMenu;
83
111
  const isCloud = rta.getFlexSettings().isCloud;
112
+ const resources = await getTextBundle();
113
+ const isReuseComponentChecker = await getReuseComponentChecker(ui5VersionInfo);
84
114
  contextMenu.addMenuItem({
85
115
  id: 'ADD_FRAGMENT',
86
- text: getAddFragmentItemText,
116
+ text: overlay => getAddFragmentItemText(overlay, isReuseComponentChecker, isCloud, resources),
87
117
  handler: async overlays => await DialogFactory.createDialog(overlays[0], rta, DialogNames.ADD_FRAGMENT),
88
118
  icon: 'sap-icon://attachment-html',
89
- enabled: overlays => isFragmentCommandEnabled(overlays, ui5VersionInfo)
119
+ enabled: overlays => isFragmentCommandEnabled(overlays, isReuseComponentChecker, isCloud)
90
120
  });
91
121
  contextMenu.addMenuItem({
92
122
  id: 'EXTEND_CONTROLLER',
93
- text: 'Extend With Controller',
123
+ text: overlay => getExtendControllerItemText(overlay, isReuseComponentChecker, isCloud, resources),
94
124
  handler: async overlays => await DialogFactory.createDialog(overlays[0], rta, DialogNames.CONTROLLER_EXTENSION),
95
125
  icon: 'sap-icon://create-form',
96
- enabled: overlays => isControllerExtensionEnabled(overlays, syncViewsIds, ui5VersionInfo, isCloud)
126
+ enabled: overlays => isControllerExtensionEnabled(overlays, syncViewsIds, isReuseComponentChecker, isCloud)
97
127
  });
98
128
  };
99
129
  var __exports = {
@@ -103,6 +133,7 @@ sap.ui.define(["sap/ui/rta/util/hasStableId", "sap/ui/fl/Utils", "../cpe/utils",
103
133
  __exports.isControllerExtensionEnabled = isControllerExtensionEnabled;
104
134
  __exports.isFragmentCommandEnabled = isFragmentCommandEnabled;
105
135
  __exports.getAddFragmentItemText = getAddFragmentItemText;
136
+ __exports.getExtendControllerItemText = getExtendControllerItemText;
106
137
  __exports.initDialogs = initDialogs;
107
138
  return __exports;
108
139
  });
@@ -12,16 +12,18 @@ import FlUtils from 'sap/ui/fl/Utils';
12
12
  import type ElementOverlay from 'sap/ui/dt/ElementOverlay';
13
13
 
14
14
  import ManagedObject from 'sap/ui/base/ManagedObject';
15
- import { isReuseComponent } from '../cpe/utils';
16
- import { Ui5VersionInfo } from '../utils/version';
17
15
  import { DialogFactory, DialogNames } from './dialog-factory';
16
+ import type { IsReuseComponentApi } from '../cpe/types';
17
+ import { getTextBundle, type TextBundle } from '../i18n';
18
+ import { getReuseComponentChecker } from './utils';
19
+ import type { Ui5VersionInfo } from '../utils/version';
18
20
 
19
21
  /**
20
22
  * Handler for enablement of Extend With Controller context menu entry
21
23
  *
22
24
  * @param control UI5 control.
23
25
  * @param syncViewsIds Runtime Authoring
24
- * @param ui5VersionInfo UI5 version information
26
+ * @param isReuseComponent Function to check if the control is a reuse component.
25
27
  * @param isCloud Whether the application is running in the cloud
26
28
  *
27
29
  * @returns boolean whether menu item is enabled or not
@@ -29,14 +31,14 @@ import { DialogFactory, DialogNames } from './dialog-factory';
29
31
  export function isControllerExtensionEnabledForControl(
30
32
  control: ManagedObject,
31
33
  syncViewsIds: string[],
32
- ui5VersionInfo: Ui5VersionInfo,
34
+ isReuseComponent: IsReuseComponentApi,
33
35
  isCloud: boolean
34
36
  ): boolean {
35
- const clickedControlId = FlUtils.getViewForControl(control).getId();
36
- const isControlInSyncView = syncViewsIds.includes(clickedControlId);
37
+ const viewId = FlUtils.getViewForControl(control).getId();
38
+ const isControlInSyncView = syncViewsIds.includes(viewId);
37
39
 
38
40
  if(isCloud) {
39
- const isClickedControlReuseComponent = isReuseComponent(clickedControlId, ui5VersionInfo);
41
+ const isClickedControlReuseComponent = isReuseComponent(control.getId());
40
42
  return !isControlInSyncView && !isClickedControlReuseComponent;
41
43
  }
42
44
  return !isControlInSyncView;
@@ -47,7 +49,7 @@ export function isControllerExtensionEnabledForControl(
47
49
  *
48
50
  * @param overlays Control overlays
49
51
  * @param syncViewsIds Runtime Authoring
50
- * @param ui5VersionInfo UI5 version information
52
+ * @param isReuseComponent Function to check if the control is a reuse component.
51
53
  * @param isCloud Whether the application is running in the cloud
52
54
  *
53
55
  * @returns boolean whether menu item is enabled or not
@@ -55,44 +57,72 @@ export function isControllerExtensionEnabledForControl(
55
57
  export const isControllerExtensionEnabled = (
56
58
  overlays: ElementOverlay[],
57
59
  syncViewsIds: string[],
58
- ui5VersionInfo: Ui5VersionInfo,
60
+ isReuseComponent: IsReuseComponentApi,
59
61
  isCloud: boolean
60
62
  ): boolean => {
61
63
  if (overlays.length === 0 || overlays.length > 1) {
62
64
  return false;
63
65
  }
64
- return isControllerExtensionEnabledForControl(overlays[0].getElement(), syncViewsIds, ui5VersionInfo, isCloud);
66
+ return isControllerExtensionEnabledForControl(overlays[0].getElement(), syncViewsIds, isReuseComponent, isCloud);
65
67
  };
66
68
 
67
69
  /**
68
70
  * Determines whether the fragment command should be enabled based on the provided overlays.
69
71
  *
70
72
  * @param {ElementOverlay[]} overlays - An array of ElementOverlay objects representing the UI overlays.
71
- * @param ui5VersionInfo UI5 version information
73
+ * @param {isReuseComponentApi} isReuseComponent - Function to check if the control is a reuse component.
74
+ * @param {boolean} isCloud - Whether the application is running in the cloud.
72
75
  * @returns {boolean} True if the fragment command is enabled, false otherwise.
73
76
  */
74
- export const isFragmentCommandEnabled = (overlays: ElementOverlay[], ui5VersionInfo: Ui5VersionInfo): boolean => {
77
+ export const isFragmentCommandEnabled = (overlays: ElementOverlay[], isReuseComponent: IsReuseComponentApi, isCloud: boolean): boolean => {
75
78
  if (overlays.length === 0 || overlays.length > 1) {
76
79
  return false;
77
80
  }
78
81
 
79
82
  const control = overlays[0].getElement();
83
+ const stableId = hasStableId(overlays[0]);
84
+ if (isCloud) {
85
+ return stableId && !isReuseComponent(control.getId());
86
+ }
80
87
 
81
- return hasStableId(overlays[0]) && !isReuseComponent(control.getId(), ui5VersionInfo);
88
+ return stableId;
82
89
  };
83
90
 
84
91
  /**
85
92
  * Determines the text that should be displayed for the Add Fragment context menu item.
86
93
  *
87
94
  * @param {ElementOverlay} overlay - An ElementOverlay object representing the UI overlay.
95
+ * @param {isReuseComponentApi} isReuseComponentChecker - Function to check if the control is a reuse component.
96
+ * @param {boolean} isCloud - Whether the application is running in the cloud.
97
+ * @param {TextBundle} resources - The text bundle.
88
98
  * @returns {string} The text of the Add Fragment context menu item.
89
99
  */
90
- export const getAddFragmentItemText = (overlay: ElementOverlay) => {
100
+ export const getAddFragmentItemText = (overlay: ElementOverlay, isReuseComponentChecker: IsReuseComponentApi, isCloud: boolean, resources: TextBundle) => {
101
+ if (isCloud && isReuseComponentChecker(overlay.getElement().getId())) {
102
+ return resources.getText('ADP_ADD_FRAGMENT_MENU_ITEM_REUSE_COMPONENT');
103
+ }
91
104
  if (!hasStableId(overlay)) {
92
- return 'Add: Fragment (Unavailable due to unstable ID of the control or its parent control)';
105
+ return resources.getText('ADP_ADD_FRAGMENT_MENU_ITEM_UNSTABLE_ID');
106
+ }
107
+
108
+ return resources.getText('ADP_ADD_FRAGMENT_MENU_ITEM');
109
+ };
110
+
111
+ /**
112
+ * Determines the text that should be displayed for Controller Extension context menu item.
113
+ *
114
+ * @param {ElementOverlay} overlay - An ElementOverlay object representing the UI overlay.
115
+ * @param {isReuseComponentApi} isReuseComponentChecker - Function to check if the control is a reuse component.
116
+ * @param {boolean} isCloud - Whether the application is running in the cloud.
117
+ * @param {TextBundle} resources - The text bundle.
118
+ * @returns {string} The text of the Add Fragment context menu item.
119
+ */
120
+ export const getExtendControllerItemText = (overlay: ElementOverlay, isReuseComponentChecker: IsReuseComponentApi, isCloud: boolean, resources: TextBundle) => {
121
+ if (isCloud && isReuseComponentChecker(overlay.getElement().getId())) {
122
+ return resources.getText('ADP_ADD_CONTROLLER_EXTENSION_MENU_ITEM_REUSE_COMPONENT');
93
123
  }
94
124
 
95
- return 'Add: Fragment';
125
+ return resources.getText('ADP_ADD_CONTROLLER_EXTENSION_MENU_ITEM');
96
126
  };
97
127
 
98
128
  /**
@@ -102,25 +132,27 @@ export const getAddFragmentItemText = (overlay: ElementOverlay) => {
102
132
  * @param syncViewsIds Ids of all application sync views
103
133
  * @param ui5VersionInfo UI5 version information
104
134
  */
105
- export const initDialogs = (rta: RuntimeAuthoring, syncViewsIds: string[], ui5VersionInfo: Ui5VersionInfo): void => {
135
+ export const initDialogs = async (rta: RuntimeAuthoring, syncViewsIds: string[], ui5VersionInfo: Ui5VersionInfo): Promise<void> => {
106
136
  const contextMenu = rta.getDefaultPlugins().contextMenu;
107
137
  const isCloud = rta.getFlexSettings().isCloud;
138
+ const resources = await getTextBundle();
139
+ const isReuseComponentChecker = await getReuseComponentChecker(ui5VersionInfo);
108
140
 
109
141
  contextMenu.addMenuItem({
110
142
  id: 'ADD_FRAGMENT',
111
- text: getAddFragmentItemText,
143
+ text: (overlay: ElementOverlay) => getAddFragmentItemText(overlay, isReuseComponentChecker, isCloud, resources),
112
144
  handler: async (overlays: UI5Element[]) =>
113
145
  await DialogFactory.createDialog(overlays[0], rta, DialogNames.ADD_FRAGMENT),
114
146
  icon: 'sap-icon://attachment-html',
115
- enabled: (overlays: ElementOverlay[]) => isFragmentCommandEnabled(overlays, ui5VersionInfo)
147
+ enabled: (overlays: ElementOverlay[]) => isFragmentCommandEnabled(overlays, isReuseComponentChecker, isCloud)
116
148
  });
117
149
 
118
150
  contextMenu.addMenuItem({
119
151
  id: 'EXTEND_CONTROLLER',
120
- text: 'Extend With Controller',
152
+ text: (overlay: ElementOverlay) => getExtendControllerItemText(overlay, isReuseComponentChecker, isCloud, resources),
121
153
  handler: async (overlays: UI5Element[]) =>
122
154
  await DialogFactory.createDialog(overlays[0], rta, DialogNames.CONTROLLER_EXTENSION),
123
155
  icon: 'sap-icon://create-form',
124
- enabled: (overlays: ElementOverlay[]) => isControllerExtensionEnabled(overlays, syncViewsIds, ui5VersionInfo, isCloud)
156
+ enabled: (overlays: ElementOverlay[]) => isControllerExtensionEnabled(overlays, syncViewsIds, isReuseComponentChecker, isCloud)
125
157
  });
126
158
  };
@@ -47,7 +47,7 @@ sap.ui.define([
47
47
  }
48
48
  const ui5VersionInfo = await getUi5Version();
49
49
  const syncViewsIds = await getAllSyncViewsIds(ui5VersionInfo);
50
- initDialogs(rta, syncViewsIds, ui5VersionInfo);
50
+ await initDialogs(rta, syncViewsIds, ui5VersionInfo);
51
51
  if (!isLowerThanMinimalUi5Version(ui5VersionInfo, {
52
52
  major: 1,
53
53
  minor: 78
@@ -22,7 +22,8 @@ export default async function (rta: RuntimeAuthoring) {
22
22
 
23
23
  const ui5VersionInfo = await getUi5Version();
24
24
  const syncViewsIds = await getAllSyncViewsIds(ui5VersionInfo);
25
- initDialogs(rta, syncViewsIds, ui5VersionInfo);
25
+
26
+ await initDialogs(rta, syncViewsIds, ui5VersionInfo);
26
27
 
27
28
  if (!isLowerThanMinimalUi5Version(ui5VersionInfo, { major: 1, minor: 78 })) {
28
29
  const ExtensionPointService = (await import('open/ux/preview/client/adp/extension-point')).default;