@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.
- package/dist/client/adp/controllers/AddActionFragment.controller.js +200 -0
- package/dist/client/adp/controllers/AddActionFragment.controller.ts +230 -0
- package/dist/client/adp/controllers/AddCustomFragment.controller.ts +1 -8
- package/dist/client/adp/controllers/AddSubpage.controller.js +1 -1
- package/dist/client/adp/controllers/AddSubpage.controller.ts +2 -12
- package/dist/client/adp/controllers/types.js +2 -0
- package/dist/client/adp/controllers/types.ts +10 -0
- package/dist/client/adp/dialog-factory.js +9 -1
- package/dist/client/adp/dialog-factory.ts +15 -0
- package/dist/client/adp/quick-actions/add-new-subpage-quick-action-base.ts +2 -1
- package/dist/client/adp/quick-actions/fe-v4/add-new-subpage.ts +1 -1
- package/dist/client/adp/quick-actions/fe-v4/create-page-action.js +81 -0
- package/dist/client/adp/quick-actions/fe-v4/create-page-action.ts +98 -0
- package/dist/client/adp/quick-actions/fe-v4/op-add-custom-section.ts +1 -1
- package/dist/client/adp/quick-actions/fe-v4/registry.js +2 -2
- package/dist/client/adp/quick-actions/fe-v4/registry.ts +1 -1
- package/dist/client/adp/quick-actions/supported-ui5versions.md +1 -1
- package/dist/client/adp/ui/AddAction.fragment.xml +49 -0
- package/dist/client/cpe/changes/service.js +17 -0
- package/dist/client/cpe/changes/service.ts +17 -0
- package/dist/client/messagebundle.properties +8 -1
- package/dist/client/utils/fe-v4.js +5 -1
- package/dist/client/utils/fe-v4.ts +5 -2
- package/package.json +8 -8
|
@@ -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,
|
|
@@ -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
|
|
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/
|
|
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/
|
|
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", "
|
|
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 =
|
|
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 '
|
|
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 | | | | |
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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"
|