@sap-ux/preview-middleware 0.23.93 → 0.23.95

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.
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+
3
+ sap.ui.define(["./BaseDialog.controller", "sap/ui/model/json/JSONModel", "../../i18n", "open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common", "../../utils/info-center-message", "../command-executor", "../../utils/error", "sap/ui/core/library"], function (__BaseDialog, JSONModel, ____i18n, ___sap_ux_private_control_property_editor_common, ____utils_info_center_message, __CommandExecutor, ____utils_error, sap_ui_core_library) {
4
+ "use strict";
5
+
6
+ function _interopRequireDefault(obj) {
7
+ return obj && obj.__esModule && typeof obj.default !== "undefined" ? obj.default : obj;
8
+ }
9
+ const BaseDialog = _interopRequireDefault(__BaseDialog);
10
+ const getResourceModel = ____i18n["getResourceModel"];
11
+ const getTextBundle = ____i18n["getTextBundle"];
12
+ const MessageBarType = ___sap_ux_private_control_property_editor_common["MessageBarType"];
13
+ const sendInfoCenterMessage = ____utils_info_center_message["sendInfoCenterMessage"];
14
+ const CommandExecutor = _interopRequireDefault(__CommandExecutor);
15
+ const getError = ____utils_error["getError"];
16
+ const ValueState = sap_ui_core_library["ValueState"];
17
+ /**
18
+ * Validates Action ID input.
19
+ *
20
+ * @param input control of action ID to validate
21
+ * @param resource text bundle for messages
22
+ * @param validateForDuplicateId custom validation function
23
+ * @return validation result
24
+ */
25
+ function validateActionId(input, resource, validateForDuplicateId) {
26
+ const actionId = input.getValue();
27
+ // Check if empty
28
+ if (!actionId || actionId.trim().length === 0) {
29
+ return {
30
+ isValid: false,
31
+ errorMessage: resource.getText('ACTION_ID_REQUIRED')
32
+ };
33
+ }
34
+ if (typeof validateForDuplicateId === 'function' && !validateForDuplicateId(actionId)) {
35
+ return {
36
+ isValid: false,
37
+ errorMessage: resource.getText('ACTION_WITH_GIVEN_ID_ALREADY_EXISTS', [actionId])
38
+ };
39
+ }
40
+
41
+ // Check for spaces
42
+ if (actionId.includes(' ')) {
43
+ return {
44
+ isValid: false,
45
+ errorMessage: resource.getText('ACTION_ID_CANNOT_CONTAIN_SPACES')
46
+ };
47
+ }
48
+
49
+ // Check starts and only allowed characters
50
+ if (!/(^([A-Za-z_][-A-Za-z0-9_.:]*)$)/.test(actionId)) {
51
+ return {
52
+ isValid: false,
53
+ errorMessage: resource.getText('ACTION_ID_INVALID_FORMAT')
54
+ };
55
+ }
56
+ return {
57
+ isValid: true,
58
+ errorMessage: ''
59
+ };
60
+ }
61
+ const AddActionFragment = BaseDialog.extend("src.adp.controllers.AddActionFragment", {
62
+ constructor: function _constructor(name, overlays, rta, options, telemetryData) {
63
+ BaseDialog.prototype.constructor.call(this, name, telemetryData);
64
+ this.options = options;
65
+ this.rta = rta;
66
+ this.overlays = overlays;
67
+ this.model = new JSONModel({
68
+ title: options.title
69
+ });
70
+ this.commandExecutor = new CommandExecutor(this.rta);
71
+ },
72
+ /**
73
+ * Setups the Dialog and the JSON Model
74
+ *
75
+ * @param {Dialog} dialog - Dialog instance
76
+ */
77
+ setup: async function _setup(dialog) {
78
+ this.dialog = dialog;
79
+ this.setEscapeHandler();
80
+ this.bundle = await getTextBundle();
81
+ await this.buildDialogData();
82
+ const resourceModel = await getResourceModel('open.ux.preview.client');
83
+ this.dialog.setModel(resourceModel, 'i18n');
84
+ this.dialog.setModel(this.model);
85
+ this.dialog.open();
86
+ },
87
+ /**
88
+ * Handles create button press
89
+ *
90
+ * @param event Event
91
+ */
92
+ onCreateBtnPress: async function _onCreateBtnPress(event) {
93
+ const source = event.getSource();
94
+ source.setEnabled(false);
95
+ await BaseDialog.prototype.onCreateBtnPressHandler.call(this);
96
+ const actionId = this.model.getProperty('/actionId');
97
+ const buttonText = this.model.getProperty('/buttonText');
98
+ await this.createAppDescriptorChangeForV4(`${this.options.propertyPath}${actionId}`, buttonText);
99
+ this.handleDialogClose();
100
+ },
101
+ /**
102
+ * Builds data that is used in the dialog
103
+ */
104
+ buildDialogData: async function _buildDialogData() {
105
+ try {
106
+ let hasController = false;
107
+ if (this.options.controllerReference) {
108
+ this.model.setProperty('/handlerReference', this.options.controllerReference);
109
+ hasController = true;
110
+ }
111
+ this.model.setProperty('/hasController', hasController);
112
+ } catch (e) {
113
+ const error = getError(e);
114
+ await sendInfoCenterMessage({
115
+ title: {
116
+ key: 'ADP_GET_FRAGMENTS_FAILURE_TITLE'
117
+ },
118
+ description: error.message,
119
+ type: MessageBarType.error
120
+ });
121
+ throw error;
122
+ }
123
+ },
124
+ /**
125
+ * Checks input values for duplicates and updates confirmation button state based on input validation states
126
+ */
127
+ updateFormState: function _updateFormState() {
128
+ const form = this.dialog.getContent()[0];
129
+ const formContent = form.getContent();
130
+ const inputs = formContent.filter(item => item.isA('sap.m.Input'));
131
+ const beginBtn = this.dialog.getBeginButton();
132
+ // Exclude the last input (display-only) from validation
133
+ // Only validate inputs that are visible and editable
134
+ const validatableInputs = inputs.filter(input => input.getVisible() && input.getEditable());
135
+ beginBtn.setEnabled(validatableInputs.every(input => input.getValueState() === ValueState.Success));
136
+ },
137
+ /**
138
+ * Handles action id input change
139
+ *
140
+ * @param event Event
141
+ */
142
+ onActionIdInputChange: function _onActionIdInputChange(event) {
143
+ // update model value
144
+ const input = event.getSource();
145
+ let modelValue = input.getValue();
146
+ if (modelValue.length < 1) {
147
+ modelValue = null;
148
+ }
149
+ this.model.setProperty('/actionId', modelValue);
150
+ const result = validateActionId(input, this.bundle, this.options.validateActionId);
151
+ if (result.isValid) {
152
+ input.setValueState(ValueState.Success).setValueStateText('');
153
+ } else {
154
+ input.setValueState(ValueState.Error).setValueStateText(result.errorMessage);
155
+ }
156
+ this.updateFormState();
157
+ },
158
+ onButtonTextInputChange: function _onButtonTextInputChange(event) {
159
+ // update model value
160
+ const input = event.getSource();
161
+ let modelValue = input.getValue();
162
+ if (modelValue.length < 1) {
163
+ modelValue = null;
164
+ }
165
+ this.model.setProperty('/buttonText', modelValue);
166
+ if (modelValue && modelValue.length > 0) {
167
+ input.setValueState(ValueState.Success).setValueStateText('');
168
+ } else {
169
+ input.setValueState(ValueState.Error).setValueStateText(this.bundle.getText('BUTTON_TEXT_REQUIRED'));
170
+ }
171
+ this.updateFormState();
172
+ },
173
+ createAppDescriptorChangeForV4: async function _createAppDescriptorChangeForV(propertyPath, actionLabel) {
174
+ const flexSettings = this.rta.getFlexSettings();
175
+ const modifiedValue = {
176
+ reference: this.options.appDescriptor?.projectId,
177
+ appComponent: this.options.appDescriptor?.appComponent,
178
+ changeType: 'appdescr_fe_changePageConfiguration',
179
+ parameters: {
180
+ page: this.options.appDescriptor?.pageId,
181
+ entityPropertyChange: {
182
+ propertyPath: `${propertyPath}`,
183
+ // e.g. 'content/body/sections/test'
184
+ operation: 'UPSERT',
185
+ propertyValue: {
186
+ press: this.options.controllerReference,
187
+ visible: true,
188
+ enabled: true,
189
+ text: actionLabel
190
+ }
191
+ }
192
+ }
193
+ };
194
+ const command = await this.commandExecutor.getCommand(this.getRuntimeControl(), 'appDescriptor', modifiedValue, flexSettings);
195
+ await this.commandExecutor.pushAndExecuteCommand(command);
196
+ }
197
+ });
198
+ return AddActionFragment;
199
+ });
200
+ //# sourceMappingURL=AddActionFragment.controller.js.map
@@ -0,0 +1,230 @@
1
+ import RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
2
+ import { PageDescriptorV4 } from './types';
3
+ import UI5Element from 'sap/ui/core/Element';
4
+ import BaseDialog from './BaseDialog.controller';
5
+ import { QuickActionTelemetryData } from '../../cpe/quick-actions/quick-action-definition';
6
+ import JSONModel from 'sap/ui/model/json/JSONModel';
7
+ import Dialog from 'sap/m/Dialog';
8
+ import { getResourceModel, getTextBundle, TextBundle } from '../../i18n';
9
+ import { MessageBarType } from '@sap-ux-private/control-property-editor-common';
10
+ import Button from 'sap/m/Button';
11
+ import { sendInfoCenterMessage } from '../../utils/info-center-message';
12
+ import Input from 'sap/m/Input';
13
+ import CommandExecutor from '../command-executor';
14
+ import Event from 'sap/ui/base/Event';
15
+ import { getError } from '../../utils/error';
16
+ import { ValueState } from 'sap/ui/core/library';
17
+ import FlexCommand from 'sap/ui/rta/command/FlexCommand';
18
+ import SimpleForm from 'sap/ui/layout/form';
19
+ import Control from 'sap/ui/core/Control';
20
+
21
+ type AddActionFragmentsModel = JSONModel & {
22
+ getProperty(sPath: '/title'): string;
23
+ getProperty(sPath: '/buttonText'): string;
24
+ getProperty(sPath: '/actionId'): string;
25
+ getProperty(sPath: '/handlerReference'): string;
26
+ getProperty(sPath: '/hasController'): boolean;
27
+ };
28
+
29
+ export interface AddActionOptions {
30
+ name: string;
31
+ propertyPath: string;
32
+ title: string;
33
+ controllerReference: string;
34
+ appDescriptor?: PageDescriptorV4;
35
+ validateActionId?: (actionId: string) => boolean;
36
+ }
37
+
38
+ /**
39
+ * Validates Action ID input.
40
+ *
41
+ * @param input control of action ID to validate
42
+ * @param resource text bundle for messages
43
+ * @param validateForDuplicateId custom validation function
44
+ * @return validation result
45
+ */
46
+ function validateActionId(
47
+ input: Input,
48
+ resource: TextBundle,
49
+ validateForDuplicateId?: (actionId: string) => boolean
50
+ ): { isValid: boolean; errorMessage: string } {
51
+ const actionId = input.getValue();
52
+ // Check if empty
53
+ if (!actionId || actionId.trim().length === 0) {
54
+ return { isValid: false, errorMessage: resource.getText('ACTION_ID_REQUIRED') };
55
+ }
56
+
57
+ if (typeof validateForDuplicateId === 'function' && !validateForDuplicateId(actionId)) {
58
+ return { isValid: false, errorMessage: resource.getText('ACTION_WITH_GIVEN_ID_ALREADY_EXISTS', [actionId]) };
59
+ }
60
+
61
+ // Check for spaces
62
+ if (actionId.includes(' ')) {
63
+ return { isValid: false, errorMessage: resource.getText('ACTION_ID_CANNOT_CONTAIN_SPACES') };
64
+ }
65
+
66
+ // Check starts and only allowed characters
67
+ if (!/(^([A-Za-z_][-A-Za-z0-9_.:]*)$)/.test(actionId)) {
68
+ return { isValid: false, errorMessage: resource.getText('ACTION_ID_INVALID_FORMAT') };
69
+ }
70
+ return { isValid: true, errorMessage: '' };
71
+ }
72
+
73
+ export default class AddActionFragment extends BaseDialog<AddActionFragmentsModel> {
74
+ private bundle: TextBundle;
75
+ constructor(
76
+ name: string,
77
+ overlays: UI5Element,
78
+ rta: RuntimeAuthoring,
79
+ readonly options: AddActionOptions,
80
+ telemetryData?: QuickActionTelemetryData
81
+ ) {
82
+ super(name, telemetryData);
83
+ this.rta = rta;
84
+ this.overlays = overlays;
85
+ this.model = new JSONModel({
86
+ title: options.title
87
+ });
88
+ this.commandExecutor = new CommandExecutor(this.rta);
89
+ }
90
+
91
+ /**
92
+ * Setups the Dialog and the JSON Model
93
+ *
94
+ * @param {Dialog} dialog - Dialog instance
95
+ */
96
+ async setup(dialog: Dialog): Promise<void> {
97
+ this.dialog = dialog;
98
+
99
+ this.setEscapeHandler();
100
+ this.bundle = await getTextBundle();
101
+ await this.buildDialogData();
102
+ const resourceModel = await getResourceModel('open.ux.preview.client');
103
+
104
+ this.dialog.setModel(resourceModel, 'i18n');
105
+ this.dialog.setModel(this.model);
106
+
107
+ this.dialog.open();
108
+ }
109
+
110
+ /**
111
+ * Handles create button press
112
+ *
113
+ * @param event Event
114
+ */
115
+ async onCreateBtnPress(event: Event) {
116
+ const source = event.getSource<Button>();
117
+ source.setEnabled(false);
118
+ await super.onCreateBtnPressHandler();
119
+
120
+ const actionId = this.model.getProperty('/actionId');
121
+ const buttonText = this.model.getProperty('/buttonText');
122
+ await this.createAppDescriptorChangeForV4(`${this.options.propertyPath}${actionId}`, buttonText);
123
+ this.handleDialogClose();
124
+ }
125
+
126
+ /**
127
+ * Builds data that is used in the dialog
128
+ */
129
+ async buildDialogData(): Promise<void> {
130
+ try {
131
+ let hasController = false;
132
+ if (this.options.controllerReference) {
133
+ this.model.setProperty('/handlerReference', this.options.controllerReference);
134
+ hasController = true;
135
+ }
136
+ this.model.setProperty('/hasController', hasController);
137
+ } catch (e) {
138
+ const error = getError(e);
139
+ await sendInfoCenterMessage({
140
+ title: { key: 'ADP_GET_FRAGMENTS_FAILURE_TITLE' },
141
+ description: error.message,
142
+ type: MessageBarType.error
143
+ });
144
+ throw error;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Checks input values for duplicates and updates confirmation button state based on input validation states
150
+ */
151
+ private updateFormState(): void {
152
+ const form = this.dialog.getContent()[0] as unknown as SimpleForm<Control[]>;
153
+ const formContent = form.getContent();
154
+ const inputs = formContent.filter((item) => item.isA('sap.m.Input')) as Input[];
155
+
156
+ const beginBtn = this.dialog.getBeginButton();
157
+ // Exclude the last input (display-only) from validation
158
+ // Only validate inputs that are visible and editable
159
+ const validatableInputs = inputs.filter((input) => input.getVisible() && input.getEditable());
160
+ beginBtn.setEnabled(validatableInputs.every((input) => input.getValueState() === ValueState.Success));
161
+ }
162
+
163
+ /**
164
+ * Handles action id input change
165
+ *
166
+ * @param event Event
167
+ */
168
+ onActionIdInputChange(event: Event): void {
169
+ // update model value
170
+ const input = event.getSource<Input>();
171
+ let modelValue: string | null = input.getValue();
172
+ if (modelValue.length < 1) {
173
+ modelValue = null;
174
+ }
175
+ this.model.setProperty('/actionId', modelValue);
176
+ const result = validateActionId(input, this.bundle, this.options.validateActionId);
177
+ if (result.isValid) {
178
+ input.setValueState(ValueState.Success).setValueStateText('');
179
+ } else {
180
+ input.setValueState(ValueState.Error).setValueStateText(result.errorMessage);
181
+ }
182
+ this.updateFormState();
183
+ }
184
+
185
+ onButtonTextInputChange(event: Event): void {
186
+ // update model value
187
+ const input = event.getSource<Input>();
188
+ let modelValue: string | null = input.getValue();
189
+ if (modelValue.length < 1) {
190
+ modelValue = null;
191
+ }
192
+ this.model.setProperty('/buttonText', modelValue);
193
+ if (modelValue && modelValue.length > 0) {
194
+ input.setValueState(ValueState.Success).setValueStateText('');
195
+ } else {
196
+ input.setValueState(ValueState.Error).setValueStateText(this.bundle.getText('BUTTON_TEXT_REQUIRED'));
197
+ }
198
+ this.updateFormState();
199
+ }
200
+
201
+ private async createAppDescriptorChangeForV4(propertyPath: string, actionLabel: string) {
202
+ const flexSettings = this.rta.getFlexSettings();
203
+ const modifiedValue = {
204
+ reference: this.options.appDescriptor?.projectId,
205
+ appComponent: this.options.appDescriptor?.appComponent,
206
+ changeType: 'appdescr_fe_changePageConfiguration',
207
+ parameters: {
208
+ page: this.options.appDescriptor?.pageId,
209
+ entityPropertyChange: {
210
+ propertyPath: `${propertyPath}`, // e.g. 'content/body/sections/test'
211
+ operation: 'UPSERT',
212
+ propertyValue: {
213
+ press: this.options.controllerReference,
214
+ visible: true,
215
+ enabled: true,
216
+ text: actionLabel
217
+ }
218
+ }
219
+ }
220
+ };
221
+ const command = await this.commandExecutor.getCommand<FlexCommand>(
222
+ this.getRuntimeControl(),
223
+ 'appDescriptor',
224
+ modifiedValue,
225
+ flexSettings
226
+ );
227
+
228
+ await this.commandExecutor.pushAndExecuteCommand(command);
229
+ }
230
+ }
@@ -22,21 +22,14 @@ import { QuickActionTelemetryData } from '../../cpe/quick-actions/quick-action-d
22
22
  import { MessageBarType, setApplicationRequiresReload } from '@sap-ux-private/control-property-editor-common';
23
23
  import { CommunicationService } from '../../cpe/communication-service';
24
24
  import FlexCommand from 'sap/ui/rta/command/FlexCommand';
25
- import type AppComponentV4 from 'sap/fe/core/AppComponent';
26
25
  import { sendInfoCenterMessage } from '../../utils/info-center-message';
27
26
  import { getError } from '../../utils/error';
27
+ import { PageDescriptorV4 } from './types';
28
28
 
29
29
  export type AddFragmentModel = JSONModel & {
30
30
  getProperty(sPath: '/title'): string;
31
31
  getProperty(sPath: '/newFragmentName'): string;
32
32
  };
33
- export interface PageDescriptorV4 {
34
- appType: 'fe-v4';
35
- appComponent: AppComponentV4;
36
- pageId: string;
37
- projectId: string;
38
- anchor: string;
39
- }
40
33
 
41
34
  export interface AddCustomFragmentOptions {
42
35
  title: string;
@@ -83,7 +83,7 @@ sap.ui.define(["sap/ui/model/json/JSONModel", "../../i18n", "../command-executor
83
83
  }
84
84
  }
85
85
  };
86
- } else {
86
+ } else if (pageDescriptor.routePattern) {
87
87
  const routePattern = generateRoutePattern(pageDescriptor.routePattern, navProperty, targetEntitySet);
88
88
  modifiedValue = {
89
89
  appComponent: pageDescriptor.appComponent,
@@ -15,9 +15,6 @@ 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
18
  /** sap.suite.ui.generic */
22
19
  import type AppComponentV2 from 'sap/suite/ui/generic/template/lib/AppComponent';
23
20
 
@@ -32,6 +29,7 @@ import { CommunicationService } from '../../cpe/communication-service';
32
29
  import { setApplicationRequiresReload } from '@sap-ux-private/control-property-editor-common';
33
30
  import { generateRoutePattern } from '../quick-actions/fe-v4/utils';
34
31
  import { QuickActionTelemetryData } from '../../cpe/quick-actions/quick-action-definition';
32
+ import { PageDescriptorV4 } from './types';
35
33
 
36
34
  type SubpageType = 'ObjectPage' | 'CustomPage';
37
35
 
@@ -42,13 +40,6 @@ export interface PageDescriptorV2 {
42
40
  pageType: string;
43
41
  }
44
42
 
45
- export interface PageDescriptorV4 {
46
- appType: 'fe-v4';
47
- appComponent: AppComponentV4;
48
- pageId: string;
49
- routePattern: string;
50
- }
51
-
52
43
  export interface AddSubpageOptions {
53
44
  appReference: string;
54
45
  title: string;
@@ -123,7 +114,6 @@ export default class AddSubpage extends BaseDialog<AddSubpageModel> {
123
114
  source.setEnabled(false);
124
115
  await super.onCreateBtnPressHandler();
125
116
 
126
-
127
117
  const flexSettings = this.rta.getFlexSettings();
128
118
  const navProperty = this.model.getProperty('/selectedNavigation/key');
129
119
  const navigation = this.model.getProperty('/navigationData').find((item) => (item.navProperty = navProperty));
@@ -151,7 +141,7 @@ export default class AddSubpage extends BaseDialog<AddSubpageModel> {
151
141
  }
152
142
  }
153
143
  };
154
- } else {
144
+ } else if (pageDescriptor.routePattern) {
155
145
  const routePattern = generateRoutePattern(pageDescriptor.routePattern, navProperty, targetEntitySet);
156
146
  modifiedValue = {
157
147
  appComponent: pageDescriptor.appComponent,
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,10 @@
1
+ import type AppComponentV4 from 'sap/fe/core/AppComponent';
2
+ export interface PageDescriptorV4 {
3
+ appType: 'fe-v4';
4
+ appComponent: AppComponentV4;
5
+ pageId: string;
6
+ routePattern?: string;
7
+ projectId?: string;
8
+ anchor?: string;
9
+ }
10
+
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- sap.ui.define(["sap/ui/core/Fragment", "../i18n", "./controllers/AddFragment.controller", "./controllers/AddTableColumnFragments.controller", "./controllers/ControllerExtension.controller", "./controllers/ExtensionPoint.controller", "./controllers/FileExistsDialog.controller", "./controllers/AddSubpage.controller", "./controllers/AddCustomFragment.controller"], function (Fragment, ___i18n, __AddFragment, __AddTableColumnFragments, __ControllerExtension, __ExtensionPoint, __FileExistsDialog, __AddSubpage, __AddCustomFragment) {
3
+ sap.ui.define(["sap/ui/core/Fragment", "../i18n", "./controllers/AddFragment.controller", "./controllers/AddTableColumnFragments.controller", "./controllers/ControllerExtension.controller", "./controllers/ExtensionPoint.controller", "./controllers/FileExistsDialog.controller", "./controllers/AddSubpage.controller", "./controllers/AddCustomFragment.controller", "./controllers/AddActionFragment.controller"], function (Fragment, ___i18n, __AddFragment, __AddTableColumnFragments, __ControllerExtension, __ExtensionPoint, __FileExistsDialog, __AddSubpage, __AddCustomFragment, __AddActionFragment) {
4
4
  "use strict";
5
5
 
6
6
  function _interopRequireDefault(obj) {
@@ -14,8 +14,10 @@ sap.ui.define(["sap/ui/core/Fragment", "../i18n", "./controllers/AddFragment.con
14
14
  const FileExistsDialog = _interopRequireDefault(__FileExistsDialog);
15
15
  const AddSubpage = _interopRequireDefault(__AddSubpage);
16
16
  const AddCustomFragment = _interopRequireDefault(__AddCustomFragment);
17
+ const AddActionFragment = _interopRequireDefault(__AddActionFragment);
17
18
  var DialogNames = /*#__PURE__*/function (DialogNames) {
18
19
  DialogNames["ADD_FRAGMENT"] = "AddFragment";
20
+ DialogNames["ADD_ACTION"] = "AddAction";
19
21
  DialogNames["ADD_TABLE_COLUMN_FRAGMENTS"] = "AddTableColumnFragments";
20
22
  DialogNames["CONTROLLER_EXTENSION"] = "ControllerExtension";
21
23
  DialogNames["ADD_FRAGMENT_AT_EXTENSION_POINT"] = "ExtensionPoint";
@@ -70,6 +72,12 @@ sap.ui.define(["sap/ui/core/Fragment", "../i18n", "./controllers/AddFragment.con
70
72
  title: resources.getText(options.title ?? 'ADP_ADD_FRAGMENT_DIALOG_TITLE')
71
73
  });
72
74
  break;
75
+ case DialogNames.ADD_ACTION:
76
+ controller = new AddActionFragment(`open.ux.preview.client.adp.controllers.${dialogName}`, overlay, rta, {
77
+ ...options,
78
+ title: resources.getText(options.title ?? 'ADP_ADD_FRAGMENT_DIALOG_TITLE')
79
+ });
80
+ break;
73
81
  case DialogNames.ADD_TABLE_COLUMN_FRAGMENTS:
74
82
  controller = new AddTableColumnFragments(`open.ux.preview.client.adp.controllers.${dialogName}`, overlay, rta, {
75
83
  ...('aggregation' in options && {
@@ -18,9 +18,11 @@ import FileExistsDialog, { FileExistsDialogOptions } from './controllers/FileExi
18
18
  import AddSubpage, { AddSubpageOptions } from './controllers/AddSubpage.controller';
19
19
  import { QuickActionTelemetryData } from '../cpe/quick-actions/quick-action-definition';
20
20
  import AddCustomFragment, { AddCustomFragmentOptions } from './controllers/AddCustomFragment.controller';
21
+ import AddActionFragment, { AddActionOptions } from './controllers/AddActionFragment.controller';
21
22
 
22
23
  export const enum DialogNames {
23
24
  ADD_FRAGMENT = 'AddFragment',
25
+ ADD_ACTION = 'AddAction',
24
26
  ADD_TABLE_COLUMN_FRAGMENTS = 'AddTableColumnFragments',
25
27
  CONTROLLER_EXTENSION = 'ControllerExtension',
26
28
  ADD_FRAGMENT_AT_EXTENSION_POINT = 'ExtensionPoint',
@@ -32,6 +34,7 @@ export const enum DialogNames {
32
34
  type Controller =
33
35
  | AddFragment
34
36
  | AddTableColumnFragments
37
+ | AddActionFragment
35
38
  | ControllerExtension
36
39
  | ExtensionPoint
37
40
  | FileExistsDialog
@@ -72,6 +75,7 @@ export class DialogFactory {
72
75
  | Partial<AddFragmentOptions>
73
76
  | Partial<FileExistsDialogOptions>
74
77
  | AddCustomFragmentOptions
78
+ | AddActionOptions
75
79
  | AddSubpageOptions = {},
76
80
  telemetryData?: QuickActionTelemetryData
77
81
  ): Promise<void> {
@@ -109,6 +113,17 @@ export class DialogFactory {
109
113
  } as AddCustomFragmentOptions
110
114
  );
111
115
  break;
116
+ case DialogNames.ADD_ACTION:
117
+ controller = new AddActionFragment(
118
+ `open.ux.preview.client.adp.controllers.${dialogName}`,
119
+ overlay,
120
+ rta,
121
+ {
122
+ ...options,
123
+ title: resources.getText(options.title ?? 'ADP_ADD_FRAGMENT_DIALOG_TITLE')
124
+ } as AddActionOptions
125
+ );
126
+ break;
112
127
  case DialogNames.ADD_TABLE_COLUMN_FRAGMENTS:
113
128
  controller = new AddTableColumnFragments(
114
129
  `open.ux.preview.client.adp.controllers.${dialogName}`,
@@ -11,7 +11,8 @@ import { EnablementValidatorResult } from './enablement-validator';
11
11
  import { getTextBundle } from '../../i18n';
12
12
  import { SimpleQuickActionDefinitionBase } from './simple-quick-action-base';
13
13
  import { DIALOG_ENABLEMENT_VALIDATOR } from './dialog-enablement-validator';
14
- import { PageDescriptorV2, PageDescriptorV4 } from '../controllers/AddSubpage.controller';
14
+ import { PageDescriptorV2 } from '../controllers/AddSubpage.controller';
15
+ import { PageDescriptorV4 } from '../controllers/types';
15
16
 
16
17
  export const ADD_NEW_OBJECT_PAGE_ACTION = 'add-new-subpage';
17
18
  const CONTROL_TYPES = ['sap.f.DynamicPage', 'sap.uxap.ObjectPageLayout'];
@@ -9,7 +9,7 @@ import { isA } from '../../../utils/core';
9
9
  import FEObjectPageComponent from 'sap/fe/templates/ObjectPage/Component';
10
10
  import FEListReportComponent from 'sap/fe/templates/ListReport/Component';
11
11
  import { getUi5Version, isLowerThanMinimalUi5Version } from '../../../utils/version';
12
- import { PageDescriptorV4 } from '../../controllers/AddSubpage.controller';
12
+ import { PageDescriptorV4 } from '../../controllers/types';
13
13
 
14
14
  export const OBJECT_PAGE_COMPONENT_NAME_V4 = 'sap.fe.templates.ObjectPage.ObjectPage';
15
15
 
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ sap.ui.define(["sap/ui/dt/OverlayRegistry", "../../dialog-factory", "../simple-quick-action-base", "../../../utils/version", "../dialog-enablement-validator", "../../api-handler", "../../utils", "../../../utils/fe-v4", "../../../utils/core"], function (OverlayRegistry, ____dialog_factory, ___simple_quick_action_base, _____utils_version, ___dialog_enablement_validator, ____api_handler, ____utils, _____utils_fe_v4, _____utils_core) {
4
+ "use strict";
5
+
6
+ const DialogFactory = ____dialog_factory["DialogFactory"];
7
+ const DialogNames = ____dialog_factory["DialogNames"];
8
+ const SimpleQuickActionDefinitionBase = ___simple_quick_action_base["SimpleQuickActionDefinitionBase"];
9
+ const getUi5Version = _____utils_version["getUi5Version"];
10
+ const isLowerThanMinimalUi5Version = _____utils_version["isLowerThanMinimalUi5Version"];
11
+ const DIALOG_ENABLEMENT_VALIDATOR = ___dialog_enablement_validator["DIALOG_ENABLEMENT_VALIDATOR"];
12
+ const getExistingController = ____api_handler["getExistingController"];
13
+ const getControllerInfoForControl = ____utils["getControllerInfoForControl"];
14
+ const getV4AppComponent = _____utils_fe_v4["getV4AppComponent"];
15
+ const isA = _____utils_core["isA"];
16
+ const ADD_PAGE_ACTION = 'add-page-action';
17
+ const CONTROL_TYPES = ['sap.f.DynamicPageTitle', 'sap.uxap.ObjectPageLayout'];
18
+ /**
19
+ * Quick Action for adding a custom page action.
20
+ */
21
+ class AddPageActionQuickAction extends SimpleQuickActionDefinitionBase {
22
+ constructor(context) {
23
+ super(ADD_PAGE_ACTION, CONTROL_TYPES, 'QUICK_ACTION_ADD_CUSTOM_PAGE_ACTION', context, [DIALOG_ENABLEMENT_VALIDATOR]);
24
+ }
25
+ async initialize() {
26
+ this.pageId = this.context.view.getViewData()?.stableId.split('::').pop();
27
+ const version = await getUi5Version();
28
+ if (isLowerThanMinimalUi5Version(version, {
29
+ major: 1,
30
+ minor: 120
31
+ })) {
32
+ return;
33
+ }
34
+ await super.initialize();
35
+ }
36
+ async execute() {
37
+ if (this.control) {
38
+ const overlay = OverlayRegistry.getOverlay(this.control) || [];
39
+ const controlInfo = getControllerInfoForControl(this.control);
40
+ const data = await getExistingController(controlInfo.controllerName);
41
+ const controllerPath = data.controllerPathFromRoot.replaceAll(/\//g, '.').replace(/\.[^.]+$/, '');
42
+ await DialogFactory.createDialog(overlay, this.context.rta, DialogNames.ADD_ACTION, undefined, {
43
+ title: 'QUICK_ACTION_ADD_CUSTOM_PAGE_ACTION',
44
+ controllerReference: controllerPath ? `.extension.${controllerPath}.<REPLACE_WITH_YOUR_HANDLER_NAME>` : '.extension.<ApplicationId.FolderName.ScriptFilename.methodName>',
45
+ appDescriptor: {
46
+ appComponent: getV4AppComponent(this.context.view),
47
+ appType: 'fe-v4',
48
+ pageId: this.pageId,
49
+ projectId: this.context.flexSettings.projectId
50
+ },
51
+ validateActionId: actionId => {
52
+ const headerActions = [...this.context.changeService.getAllPendingConfigPropertyPath()].filter(path => path.includes('content/header/actions/'));
53
+ const idInPendingChanges = headerActions.length && headerActions.includes(`content/header/actions/${actionId}`);
54
+ if (idInPendingChanges) {
55
+ return false;
56
+ }
57
+ if (isA('sap.f.DynamicPageTitle', this.control) && this.control.getActions().every(action => !action.getId().endsWith(`CustomAction::${actionId}`))) {
58
+ return true;
59
+ }
60
+ if (isA('sap.uxap.ObjectPageLayout', this.control) && this.control.getHeaderTitle()?.getActions().every(action => !action.getId().endsWith(`CustomAction::${actionId}`))) {
61
+ return true;
62
+ }
63
+ return false;
64
+ },
65
+ propertyPath: 'content/header/actions/'
66
+ }, {
67
+ actionName: this.type,
68
+ telemetryEventIdentifier: this.getTelemetryIdentifier()
69
+ });
70
+ }
71
+ return [];
72
+ }
73
+ }
74
+ var __exports = {
75
+ __esModule: true
76
+ };
77
+ __exports.ADD_PAGE_ACTION = ADD_PAGE_ACTION;
78
+ __exports.AddPageActionQuickAction = AddPageActionQuickAction;
79
+ return __exports;
80
+ });
81
+ //# sourceMappingURL=create-page-action.js.map
@@ -0,0 +1,98 @@
1
+ import OverlayRegistry from 'sap/ui/dt/OverlayRegistry';
2
+ import FlexCommand from 'sap/ui/rta/command/FlexCommand';
3
+
4
+ import { DialogFactory, DialogNames } from '../../dialog-factory';
5
+ import { QuickActionContext, SimpleQuickActionDefinition } from '../../../cpe/quick-actions/quick-action-definition';
6
+ import { SimpleQuickActionDefinitionBase } from '../simple-quick-action-base';
7
+ import { getUi5Version, isLowerThanMinimalUi5Version } from '../../../utils/version';
8
+ import { DIALOG_ENABLEMENT_VALIDATOR } from '../dialog-enablement-validator';
9
+ import { getExistingController } from '../../api-handler';
10
+ import { getControllerInfoForControl } from '../../utils';
11
+ import { getV4AppComponent } from '../../../utils/fe-v4';
12
+ import { isA } from '../../../utils/core';
13
+ import DynamicPageTitle from 'sap/f/DynamicPageTitle';
14
+ import ObjectPageLayout from 'sap/uxap/ObjectPageLayout';
15
+ import ObjectPageDynamicHeaderTitle from 'sap/uxap/ObjectPageDynamicHeaderTitle';
16
+
17
+ export const ADD_PAGE_ACTION = 'add-page-action';
18
+ const CONTROL_TYPES = ['sap.f.DynamicPageTitle', 'sap.uxap.ObjectPageLayout'];
19
+ interface ViewDataType {
20
+ stableId: string;
21
+ }
22
+ /**
23
+ * Quick Action for adding a custom page action.
24
+ */
25
+ export class AddPageActionQuickAction extends SimpleQuickActionDefinitionBase implements SimpleQuickActionDefinition {
26
+ protected pageId: string | undefined;
27
+ constructor(context: QuickActionContext) {
28
+ super(ADD_PAGE_ACTION, CONTROL_TYPES, 'QUICK_ACTION_ADD_CUSTOM_PAGE_ACTION', context, [
29
+ DIALOG_ENABLEMENT_VALIDATOR
30
+ ]);
31
+ }
32
+
33
+ async initialize(): Promise<void> {
34
+ this.pageId = (this.context.view.getViewData() as ViewDataType)?.stableId.split('::').pop() as string;
35
+ const version = await getUi5Version();
36
+ if (isLowerThanMinimalUi5Version(version, { major: 1, minor: 120 })) {
37
+ return;
38
+ }
39
+ await super.initialize();
40
+ }
41
+
42
+ async execute(): Promise<FlexCommand[]> {
43
+ if (this.control) {
44
+ const overlay = OverlayRegistry.getOverlay(this.control) || [];
45
+ const controlInfo = getControllerInfoForControl(this.control);
46
+ const data = await getExistingController(controlInfo.controllerName);
47
+ const controllerPath = data.controllerPathFromRoot.replaceAll(/\//g, '.').replace(/\.[^.]+$/, '');
48
+ await DialogFactory.createDialog(
49
+ overlay,
50
+ this.context.rta,
51
+ DialogNames.ADD_ACTION,
52
+ undefined,
53
+ {
54
+ title: 'QUICK_ACTION_ADD_CUSTOM_PAGE_ACTION',
55
+ controllerReference: controllerPath
56
+ ? `.extension.${controllerPath}.<REPLACE_WITH_YOUR_HANDLER_NAME>`
57
+ : '.extension.<ApplicationId.FolderName.ScriptFilename.methodName>',
58
+ appDescriptor: {
59
+ appComponent: getV4AppComponent(this.context.view)!,
60
+ appType: 'fe-v4',
61
+ pageId: this.pageId!,
62
+ projectId: this.context.flexSettings.projectId
63
+ },
64
+ validateActionId: (actionId) => {
65
+ const headerActions = [...this.context.changeService.getAllPendingConfigPropertyPath()].filter(
66
+ (path) => path.includes('content/header/actions/')
67
+ );
68
+ const idInPendingChanges =
69
+ headerActions.length && headerActions.includes(`content/header/actions/${actionId}`);
70
+ if (idInPendingChanges) {
71
+ return false;
72
+ }
73
+ if (
74
+ isA('sap.f.DynamicPageTitle', this.control) &&
75
+ (this.control as DynamicPageTitle)
76
+ .getActions()
77
+ .every((action) => !action.getId().endsWith(`CustomAction::${actionId}`))
78
+ ) {
79
+ return true;
80
+ }
81
+ if (
82
+ isA('sap.uxap.ObjectPageLayout', this.control) &&
83
+ ((this.control as ObjectPageLayout).getHeaderTitle() as ObjectPageDynamicHeaderTitle)
84
+ ?.getActions()
85
+ .every((action) => !action.getId().endsWith(`CustomAction::${actionId}`))
86
+ ) {
87
+ return true;
88
+ }
89
+ return false;
90
+ },
91
+ propertyPath: 'content/header/actions/'
92
+ },
93
+ { actionName: this.type, telemetryEventIdentifier: this.getTelemetryIdentifier() }
94
+ );
95
+ }
96
+ return [];
97
+ }
98
+ }
@@ -1,5 +1,5 @@
1
1
  import { getV4AppComponent } from '../../../utils/fe-v4';
2
- import { PageDescriptorV4 } from '../../controllers/AddCustomFragment.controller';
2
+ import { PageDescriptorV4 } from '../../controllers/types';
3
3
  import { SimpleQuickActionDefinitionBase } from '../simple-quick-action-base';
4
4
  import { QuickActionContext, SimpleQuickActionDefinition } from '../../../cpe/quick-actions/quick-action-definition';
5
5
  import { OP_ADD_CUSTOM_SECTION } from '../common/op-add-custom-section';
@@ -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", "./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", "../fe-v4/change-table-actions"], function (_____cpe_quick_actions_registry, ___common_add_controller_to_page, ___lr_toggle_clear_filter_bar, ___change_table_columns, ___common_op_add_header_field, ___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, ___fe_v4_change_table_actions) {
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", "./op-add-custom-section", "./create-table-custom-column", "./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", "../fe-v4/change-table-actions"], function (_____cpe_quick_actions_registry, ___common_add_controller_to_page, ___lr_toggle_clear_filter_bar, ___change_table_columns, ___common_op_add_header_field, ___op_add_custom_section, ___create_table_custom_column, ___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, ___fe_v4_change_table_actions) {
4
4
  "use strict";
5
5
 
6
6
  const QuickActionDefinitionRegistry = _____cpe_quick_actions_registry["QuickActionDefinitionRegistry"];
@@ -10,7 +10,7 @@ sap.ui.define(["../../../cpe/quick-actions/registry", "../common/add-controller-
10
10
  const AddHeaderFieldQuickAction = ___common_op_add_header_field["AddHeaderFieldQuickAction"];
11
11
  const AddCustomSectionQuickAction = ___op_add_custom_section["AddCustomSectionQuickAction"];
12
12
  const AddTableCustomColumnQuickAction = ___create_table_custom_column["AddTableCustomColumnQuickAction"];
13
- const AddPageActionQuickAction = ___common_create_page_action["AddPageActionQuickAction"];
13
+ const AddPageActionQuickAction = ___create_page_action["AddPageActionQuickAction"];
14
14
  const AddTableActionQuickAction = ___create_table_action["AddTableActionQuickAction"];
15
15
  const EnableTableFilteringQuickAction = ___lr_enable_table_filtering["EnableTableFilteringQuickAction"];
16
16
  const ToggleSemanticDateRangeFilterBar = ___lr_enable_semantic_date_range_filter_bar["ToggleSemanticDateRangeFilterBar"];
@@ -10,7 +10,7 @@ import { ChangeTableColumnsQuickAction } from './change-table-columns';
10
10
  import { AddHeaderFieldQuickAction } from '../common/op-add-header-field';
11
11
  import { AddCustomSectionQuickAction } from './op-add-custom-section';
12
12
  import { AddTableCustomColumnQuickAction } from './create-table-custom-column';
13
- import { AddPageActionQuickAction } from '../common/create-page-action';
13
+ import { AddPageActionQuickAction } from './create-page-action';
14
14
  import { AddTableActionQuickAction } from './create-table-action';
15
15
  import { EnableTableFilteringQuickAction } from './lr-enable-table-filtering';
16
16
  import { ToggleSemanticDateRangeFilterBar } from './lr-enable-semantic-date-range-filter-bar';
@@ -9,7 +9,7 @@
9
9
  | Add Custom Section | V2 | OP | x | x | x | x | x | x | x | x | x | x | x |
10
10
  | | V4 | OP | x | x | x | x | x | x | x | x | x | x | x |
11
11
  | Add Custom Page Action | V2 | LR, ALP, OP | | | | | | | | x | x | x | x |
12
- | | V4 | LR, ALP, OP | | | | | | | | x | x | x | x |
12
+ | | V4 | LR, ALP, OP | | | | | x | x | x | x | x | x | x |
13
13
  | Add Custom Table Action | V2 | LR, ALP, OP | | | x | x | x | x | x | x | x | x | x |
14
14
  | | V4 | LR, ALP, OP | | | x | x | x | x | x | x | x | x | x |
15
15
  | Add Custom Table Column | V2 | LR, ALP, OP | | | x | x | x | x | x | x | x | x | x |
@@ -0,0 +1,49 @@
1
+ <Dialog id="addActionFragmentsDialog"
2
+ xmlns="sap.m"
3
+ xmlns:core="sap.ui.core"
4
+ xmlns:f="sap.ui.layout.form"
5
+ title="{/title}"
6
+ contentWidth="500px"
7
+ class="sapUiRTABorder">
8
+ <content>
9
+ <f:SimpleForm id="addActionFragmentsDialog_Form"
10
+ editable="true"
11
+ layout="ResponsiveGridLayout"
12
+ labelSpanS="4"
13
+ singleContainerFullSize="false">
14
+ <f:content>
15
+ <Label text="{i18n>ADP_ADD_ACTION_DIALOG_ACTION_ID_LABEL}" required="true" />
16
+ <Input
17
+ value="{/actionId}"
18
+ liveChange="onActionIdInputChange">
19
+ </Input>
20
+ <Label text="{i18n>ADP_ADD_ACTION_DIALOG_BUTTON_TEXT_LABEL}" required="true" />
21
+ <Input
22
+ value="{/buttonText}"
23
+ liveChange="onButtonTextInputChange">
24
+ </Input>
25
+ <Label text="{i18n>ADP_ADD_ACTION_DIALOG_HANDLER_METHOD_LABEL}" />
26
+ <Input
27
+ value="{/handlerReference}"
28
+ visible="{/hasController}"
29
+ editable="false"><!--Subjected to change, when handler can be provided by user -->
30
+ </Input>
31
+ </f:content>
32
+ </f:SimpleForm>
33
+ </content>
34
+ <beginButton>
35
+ <Button
36
+ id="createDialogBtn"
37
+ text="Create"
38
+ press="onCreateBtnPress"
39
+ enabled="false"
40
+ type="Emphasized" />
41
+ </beginButton>
42
+ <endButton>
43
+ <Button
44
+ id="closeDialogBtn"
45
+ text="Cancel"
46
+ press="handleDialogClose"
47
+ type="Reject" />
48
+ </endButton>
49
+ </Dialog>
@@ -53,6 +53,7 @@ sap.ui.define(["open/ux/preview/client/thirdparty/@sap-ux-private/control-proper
53
53
  eventStack = [];
54
54
  pendingConfigChangeMap = new Map();
55
55
  configPropertyControlIdMap = new Map();
56
+ configPropertyPath = new Set();
56
57
  /**
57
58
  *
58
59
  * @param options ui5 adaptation options.
@@ -323,6 +324,15 @@ sap.ui.define(["open/ux/preview/client/thirdparty/@sap-ux-private/control-proper
323
324
  return (pendingChanges || []).find(item => item.isActive && item.properties[0].label === propertyName)?.properties[0].value;
324
325
  }
325
326
 
327
+ /**
328
+ * Get all pending configuration changes.
329
+ *
330
+ * @returns array of pending generic changes
331
+ */
332
+ getAllPendingConfigPropertyPath() {
333
+ return this.configPropertyPath ?? new Set();
334
+ }
335
+
326
336
  /**
327
337
  * Update config changes with associated controls.
328
338
  *
@@ -409,6 +419,13 @@ sap.ui.define(["open/ux/preview/client/thirdparty/@sap-ux-private/control-proper
409
419
  properties
410
420
  };
411
421
  if (changeType === 'appdescr_fe_changePageConfiguration') {
422
+ const configChangePath = changeDefinition.content.entityPropertyChange.propertyPath;
423
+ if (genericChange.isActive) {
424
+ this.configPropertyPath.add(configChangePath);
425
+ } else {
426
+ // remove value from set if change is undone
427
+ this.configPropertyPath.delete(configChangePath);
428
+ }
412
429
  this.trackPendingConfigChanges(genericChange);
413
430
  }
414
431
  return genericChange;
@@ -80,6 +80,7 @@ export class ChangeService extends EventTarget {
80
80
  private readonly eventStack: object[] = [];
81
81
  private pendingConfigChangeMap: Map<string, PendingGenericChange[]> = new Map();
82
82
  private configPropertyControlIdMap: Map<string, string[]> = new Map();
83
+ private readonly configPropertyPath: Set<string> = new Set();
83
84
  /**
84
85
  *
85
86
  * @param options ui5 adaptation options.
@@ -380,6 +381,15 @@ export class ChangeService extends EventTarget {
380
381
  ?.properties[0].value;
381
382
  }
382
383
 
384
+ /**
385
+ * Get all pending configuration changes.
386
+ *
387
+ * @returns array of pending generic changes
388
+ */
389
+ public getAllPendingConfigPropertyPath(): Set<string> {
390
+ return this.configPropertyPath ?? new Set();
391
+ }
392
+
383
393
  /**
384
394
  * Update config changes with associated controls.
385
395
  *
@@ -476,6 +486,13 @@ export class ChangeService extends EventTarget {
476
486
  properties
477
487
  };
478
488
  if (changeType === 'appdescr_fe_changePageConfiguration') {
489
+ const configChangePath = (changeDefinition as ConfigChange).content.entityPropertyChange.propertyPath;
490
+ if (genericChange.isActive) {
491
+ this.configPropertyPath.add(configChangePath);
492
+ } else {
493
+ // remove value from set if change is undone
494
+ this.configPropertyPath.delete(configChangePath);
495
+ }
479
496
  this.trackPendingConfigChanges(genericChange);
480
497
  }
481
498
  return genericChange;
@@ -67,6 +67,9 @@ ADP_CREATE_CONTROLLER_EXTENSION_TITLE = Create Controller Extension
67
67
  ADP_CREATE_CONTROLLER_EXTENSION_DESCRIPTION = Controller extension with name ''{0}'' was created.
68
68
  ADP_ODATA_HEALTH_CHECK_TITLE = OData Service Health Check
69
69
  ADP_ODATA_SERVICE_DOWN_DESCRIPTION = The OData service with the {0} endpoint is down. Error: {1}.
70
+ ADP_ADD_ACTION_DIALOG_ACTION_ID_LABEL = Action ID
71
+ ADP_ADD_ACTION_DIALOG_BUTTON_TEXT_LABEL = Button Text
72
+ ADP_ADD_ACTION_DIALOG_HANDLER_METHOD_LABEL = Handler Method
70
73
  CHANGES_VISIBLE_AFTER_SAVE_AND_RELOAD_TITLE = Save and Reload Required
71
74
  CHANGES_VISIBLE_AFTER_SAVE_AND_RELOAD_DESCRIPTION = Note: The change will be visible after save and reload.
72
75
  CHANGE_CREATION_FAILED_TITLE = Change Creation Failed
@@ -129,4 +132,8 @@ TARGET_CONTROL_ID=TARGET ID
129
132
  AGGREGATION=TARGET AGGREGATION
130
133
  FRAGMENT_PATH=FRAGMENT PATH
131
134
 
132
-
135
+ ACTION_ID_REQUIRED=Action ID is required.
136
+ ACTION_WITH_GIVEN_ID_ALREADY_EXISTS=An action with the ''{0}'' ID is already defined. Please choose a different ID.
137
+ ACTION_ID_CANNOT_CONTAIN_SPACES=Action ID cannot contain spaces.
138
+ ACTION_ID_INVALID_FORMAT=Action ID must start with a letter or _ and may contain letters, digits, _, ., :, and -.
139
+ BUTTON_TEXT_REQUIRED=Button Text is required.
@@ -14,7 +14,11 @@ sap.ui.define(["sap/ui/core/Component", "./core", "sap/ui/rta/command/CommandFac
14
14
  function getV4AppComponent(control) {
15
15
  const ownerComponent = Component.getOwnerComponentFor(control);
16
16
  if (ownerComponent?.isA('sap.fe.core.TemplateComponent')) {
17
- return ownerComponent.getAppComponent();
17
+ if (ownerComponent.getAppComponent) {
18
+ return ownerComponent.getAppComponent();
19
+ } else if (ownerComponent?.oAppComponent) {
20
+ return ownerComponent.oAppComponent;
21
+ }
18
22
  }
19
23
  return undefined;
20
24
  }
@@ -20,7 +20,11 @@ import FlexCommand from 'sap/ui/rta/command/FlexCommand';
20
20
  export function getV4AppComponent(control: ManagedObject): AppComponent | undefined {
21
21
  const ownerComponent = Component.getOwnerComponentFor(control);
22
22
  if (ownerComponent?.isA<TemplateComponent>('sap.fe.core.TemplateComponent')) {
23
- return ownerComponent.getAppComponent();
23
+ if (ownerComponent.getAppComponent) {
24
+ return ownerComponent.getAppComponent();
25
+ } else if ((ownerComponent as unknown as { oAppComponent: AppComponent })?.oAppComponent) {
26
+ return (ownerComponent as unknown as { oAppComponent: AppComponent }).oAppComponent;
27
+ }
24
28
  }
25
29
  return undefined;
26
30
  }
@@ -117,7 +121,6 @@ export async function createManifestPropertyChange(
117
121
  } else {
118
122
  adjustedChanges[key] = value;
119
123
  }
120
-
121
124
  }
122
125
  const [manifestPropertyChange] = overlayData.manifestPropertyChange(
123
126
  adjustedChanges,
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "bugs": {
10
10
  "url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue+label%3Abug+label%3Apreview-middleware"
11
11
  },
12
- "version": "0.23.93",
12
+ "version": "0.23.95",
13
13
  "license": "Apache-2.0",
14
14
  "author": "@SAP/ux-tools-team",
15
15
  "main": "dist/index.js",
@@ -27,14 +27,14 @@
27
27
  "mem-fs-editor": "9.4.0",
28
28
  "qrcode": "1.5.4",
29
29
  "@sap/bas-sdk": "3.12.0",
30
- "@sap-ux/adp-tooling": "0.18.40",
30
+ "@sap-ux/adp-tooling": "0.18.41",
31
31
  "@sap-ux/btp-utils": "1.1.6",
32
- "@sap-ux/control-property-editor-sources": "npm:@sap-ux/control-property-editor@0.7.8",
33
32
  "@sap-ux/feature-toggle": "0.3.5",
33
+ "@sap-ux/control-property-editor-sources": "npm:@sap-ux/control-property-editor@0.7.8",
34
34
  "@sap-ux/logger": "0.8.0",
35
+ "@sap-ux/i18n": "0.3.7",
35
36
  "@sap-ux/project-access": "1.34.2",
36
- "@sap-ux/system-access": "0.6.41",
37
- "@sap-ux/i18n": "0.3.7"
37
+ "@sap-ux/system-access": "0.6.41"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@sap-ux-private/playwright": "0.2.5",
@@ -53,10 +53,10 @@
53
53
  "nock": "13.4.0",
54
54
  "npm-run-all2": "6.2.0",
55
55
  "supertest": "7.1.4",
56
- "@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@0.18.10",
57
- "@sap-ux/axios-extension": "1.25.6",
58
56
  "@sap-ux/store": "1.5.0",
59
- "@sap-ux/ui5-info": "0.13.7"
57
+ "@sap-ux/ui5-info": "0.13.8",
58
+ "@sap-ux/axios-extension": "1.25.6",
59
+ "@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@0.18.11"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "express": "4"