@sap-ux/preview-middleware 0.23.134 → 0.23.135
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 +1 -1
- package/dist/client/adp/controllers/AddActionFragment.controller.ts +1 -1
- package/dist/client/adp/controllers/AddCustomFragment.controller.js +111 -12
- package/dist/client/adp/controllers/AddCustomFragment.controller.ts +114 -12
- package/dist/client/adp/quick-actions/fe-v4/create-table-action-config-change.js +2 -2
- package/dist/client/adp/quick-actions/fe-v4/create-table-action-config-change.ts +9 -11
- package/dist/client/adp/quick-actions/fe-v4/create-table-custom-column-config-change.js +142 -0
- package/dist/client/adp/quick-actions/fe-v4/create-table-custom-column-config-change.ts +178 -0
- package/dist/client/adp/quick-actions/fe-v4/op-add-custom-section.js +2 -1
- package/dist/client/adp/quick-actions/fe-v4/op-add-custom-section.ts +2 -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/fe-v4/utils.js +26 -22
- package/dist/client/adp/quick-actions/fe-v4/utils.ts +34 -34
- package/dist/client/adp/quick-actions/table-quick-action-base.js +50 -6
- package/dist/client/adp/quick-actions/table-quick-action-base.ts +56 -5
- package/dist/client/adp/ui/AddCustomFragment.fragment.xml +6 -0
- package/dist/client/messagebundle.properties +5 -1
- package/dist/client/utils/fe-v4.js +12 -0
- package/dist/client/utils/fe-v4.ts +17 -0
- package/package.json +4 -4
- package/dist/client/adp/quick-actions/fe-v4/create-table-custom-column.js +0 -51
- package/dist/client/adp/quick-actions/fe-v4/create-table-custom-column.ts +0 -52
|
@@ -42,7 +42,7 @@ sap.ui.define(["./BaseDialog.controller", "sap/ui/model/json/JSONModel", "../../
|
|
|
42
42
|
if (!/(^([A-Za-z_][-A-Za-z0-9_.:]*)$)/.test(actionId)) {
|
|
43
43
|
return {
|
|
44
44
|
isValid: false,
|
|
45
|
-
errorMessage: resource.getText('
|
|
45
|
+
errorMessage: resource.getText('ID_INVALID_FORMAT', ['Action'])
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
return {
|
|
@@ -65,7 +65,7 @@ function validateActionId(
|
|
|
65
65
|
|
|
66
66
|
// Check starts and only allowed characters
|
|
67
67
|
if (!/(^([A-Za-z_][-A-Za-z0-9_.:]*)$)/.test(actionId)) {
|
|
68
|
-
return { isValid: false, errorMessage: resource.getText('
|
|
68
|
+
return { isValid: false, errorMessage: resource.getText('ID_INVALID_FORMAT', ['Action']) };
|
|
69
69
|
}
|
|
70
70
|
return { isValid: true, errorMessage: '' };
|
|
71
71
|
}
|
|
@@ -1,20 +1,58 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
sap.ui.define(["sap/ui/model/json/JSONModel", "../../i18n", "../command-executor", "
|
|
3
|
+
sap.ui.define(["sap/ui/model/json/JSONModel", "../../i18n", "../command-executor", "./BaseDialog.controller", "open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common", "../../cpe/communication-service", "../../utils/info-center-message", "../../utils/error", "sap/ui/core/library", "../api-handler"], function (JSONModel, ____i18n, __CommandExecutor, __BaseDialog, ___sap_ux_private_control_property_editor_common, ____cpe_communication_service, ____utils_info_center_message, ____utils_error, sap_ui_core_library, ___api_handler) {
|
|
4
4
|
"use strict";
|
|
5
5
|
|
|
6
6
|
function _interopRequireDefault(obj) {
|
|
7
7
|
return obj && obj.__esModule && typeof obj.default !== "undefined" ? obj.default : obj;
|
|
8
8
|
}
|
|
9
9
|
const getResourceModel = ____i18n["getResourceModel"];
|
|
10
|
+
const getTextBundle = ____i18n["getTextBundle"];
|
|
10
11
|
const CommandExecutor = _interopRequireDefault(__CommandExecutor);
|
|
11
|
-
const getFragments = ___api_handler["getFragments"];
|
|
12
12
|
const BaseDialog = _interopRequireDefault(__BaseDialog);
|
|
13
13
|
const MessageBarType = ___sap_ux_private_control_property_editor_common["MessageBarType"];
|
|
14
14
|
const setApplicationRequiresReload = ___sap_ux_private_control_property_editor_common["setApplicationRequiresReload"];
|
|
15
15
|
const CommunicationService = ____cpe_communication_service["CommunicationService"];
|
|
16
16
|
const sendInfoCenterMessage = ____utils_info_center_message["sendInfoCenterMessage"];
|
|
17
17
|
const getError = ____utils_error["getError"];
|
|
18
|
+
const ValueState = sap_ui_core_library["ValueState"];
|
|
19
|
+
const getFragments = ___api_handler["getFragments"];
|
|
20
|
+
/**
|
|
21
|
+
* Validates Control ID input.
|
|
22
|
+
*
|
|
23
|
+
* @param input control of control ID to validate
|
|
24
|
+
* @param validateForDuplicateId custom validation function
|
|
25
|
+
* @return validation result
|
|
26
|
+
*/
|
|
27
|
+
function validateControlId(input, resource, identifier = 'Column', validateForDuplicateId) {
|
|
28
|
+
const id = input.getValue();
|
|
29
|
+
// Check if empty
|
|
30
|
+
if (!id || id.trim().length === 0) {
|
|
31
|
+
return {
|
|
32
|
+
isValid: false,
|
|
33
|
+
errorMessage: resource.getText('ID_REQUIRED', [identifier])
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
if (typeof validateForDuplicateId === 'function' && !validateForDuplicateId?.(id)) {
|
|
37
|
+
return {
|
|
38
|
+
isValid: false,
|
|
39
|
+
errorMessage: resource.getText('GIVEN_ID_ALREADY_EXISTS', [identifier, id])
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Check if starts with number
|
|
44
|
+
if (!/(^([A-Za-z_][-A-Za-z0-9_.:]*)$)/.test(id)) {
|
|
45
|
+
return {
|
|
46
|
+
isValid: false,
|
|
47
|
+
errorMessage: resource.getText('ID_INVALID_FORMAT', [identifier])
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
isValid: true,
|
|
52
|
+
errorMessage: ''
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
18
56
|
/**
|
|
19
57
|
* @namespace open.ux.preview.client.adp.controllers
|
|
20
58
|
*/
|
|
@@ -37,6 +75,7 @@ sap.ui.define(["sap/ui/model/json/JSONModel", "../../i18n", "../command-executor
|
|
|
37
75
|
setup: async function _setup(dialog) {
|
|
38
76
|
this.dialog = dialog;
|
|
39
77
|
this.setEscapeHandler();
|
|
78
|
+
this.bundle = await getTextBundle();
|
|
40
79
|
await this.buildDialogData();
|
|
41
80
|
const resourceModel = await getResourceModel('open.ux.preview.client');
|
|
42
81
|
this.dialog.setModel(resourceModel, 'i18n');
|
|
@@ -58,7 +97,7 @@ sap.ui.define(["sap/ui/model/json/JSONModel", "../../i18n", "../command-executor
|
|
|
58
97
|
CommunicationService.sendAction(setApplicationRequiresReload(true));
|
|
59
98
|
await sendInfoCenterMessage({
|
|
60
99
|
title: {
|
|
61
|
-
key: 'ADP_ADD_FRAGMENT_DIALOG_TITLE'
|
|
100
|
+
key: this.options.title ?? 'ADP_ADD_FRAGMENT_DIALOG_TITLE'
|
|
62
101
|
},
|
|
63
102
|
description: {
|
|
64
103
|
key: 'ADP_ADD_FRAGMENT_NOTIFICATION',
|
|
@@ -72,6 +111,26 @@ sap.ui.define(["sap/ui/model/json/JSONModel", "../../i18n", "../command-executor
|
|
|
72
111
|
* Builds data that is used in the dialog
|
|
73
112
|
*/
|
|
74
113
|
buildDialogData: async function _buildDialogData() {
|
|
114
|
+
try {
|
|
115
|
+
let isCustomColumnFragment = false;
|
|
116
|
+
if (this.options.type === 'tableColumn') {
|
|
117
|
+
await this.addFragmentListToModel();
|
|
118
|
+
isCustomColumnFragment = true;
|
|
119
|
+
}
|
|
120
|
+
this.model.setProperty('/isCustomColumnFragment', isCustomColumnFragment);
|
|
121
|
+
} catch (e) {
|
|
122
|
+
const error = getError(e);
|
|
123
|
+
await sendInfoCenterMessage({
|
|
124
|
+
title: {
|
|
125
|
+
key: this.options.title ?? 'ADP_ADD_FRAGMENT_DIALOG_TITLE'
|
|
126
|
+
},
|
|
127
|
+
description: error.message,
|
|
128
|
+
type: MessageBarType.error
|
|
129
|
+
});
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
addFragmentListToModel: async function _addFragmentListToModel() {
|
|
75
134
|
try {
|
|
76
135
|
const {
|
|
77
136
|
fragments
|
|
@@ -81,7 +140,7 @@ sap.ui.define(["sap/ui/model/json/JSONModel", "../../i18n", "../command-executor
|
|
|
81
140
|
const error = getError(e);
|
|
82
141
|
await sendInfoCenterMessage({
|
|
83
142
|
title: {
|
|
84
|
-
key: '
|
|
143
|
+
key: 'ADP_ADD_FRAGMENT_FAILURE_TITLE'
|
|
85
144
|
},
|
|
86
145
|
description: error.message,
|
|
87
146
|
type: MessageBarType.error
|
|
@@ -89,10 +148,44 @@ sap.ui.define(["sap/ui/model/json/JSONModel", "../../i18n", "../command-executor
|
|
|
89
148
|
throw error;
|
|
90
149
|
}
|
|
91
150
|
},
|
|
151
|
+
/**
|
|
152
|
+
* Checks input values for duplicates and updates confirmation button state based on input validation states
|
|
153
|
+
*/
|
|
154
|
+
updateFormState: function _updateFormState() {
|
|
155
|
+
const form = this.dialog.getContent()[0];
|
|
156
|
+
const formContent = form.getContent();
|
|
157
|
+
const inputs = formContent.filter(item => item.isA('sap.m.Input'));
|
|
158
|
+
const beginBtn = this.dialog.getBeginButton();
|
|
159
|
+
// Exclude the last input (display-only) from validation
|
|
160
|
+
// Only validate inputs that are visible and editable
|
|
161
|
+
const validatableInputs = inputs.filter(input => input.getVisible() && input.getEditable());
|
|
162
|
+
beginBtn.setEnabled(validatableInputs.every(input => input.getValueState() === ValueState.Success));
|
|
163
|
+
},
|
|
164
|
+
/**
|
|
165
|
+
* Handles id input change
|
|
166
|
+
*
|
|
167
|
+
* @param event Event
|
|
168
|
+
*/
|
|
169
|
+
onIdInputChange: function _onIdInputChange(event) {
|
|
170
|
+
// update model value
|
|
171
|
+
const input = event.getSource();
|
|
172
|
+
let modelValue = input.getValue();
|
|
173
|
+
if (modelValue.length < 1) {
|
|
174
|
+
modelValue = null;
|
|
175
|
+
}
|
|
176
|
+
this.model.setProperty('/id', modelValue);
|
|
177
|
+
const result = validateControlId(input, this.bundle, 'Column', this.options.validateId);
|
|
178
|
+
if (result.isValid) {
|
|
179
|
+
input.setValueState(ValueState.Success).setValueStateText('');
|
|
180
|
+
} else {
|
|
181
|
+
input.setValueState(ValueState.Error).setValueStateText(result.errorMessage);
|
|
182
|
+
}
|
|
183
|
+
this.updateFormState();
|
|
184
|
+
},
|
|
92
185
|
createAppDescriptorChangeForV4: async function _createAppDescriptorChangeForV(templatePath) {
|
|
93
|
-
const
|
|
186
|
+
const id = this.options.type === 'tableColumn' ? this.model.getProperty('/id') : this.model.getProperty('/newFragmentName');
|
|
94
187
|
const template = `${this.options.appDescriptor?.projectId}.changes.${templatePath}`;
|
|
95
|
-
const
|
|
188
|
+
const anchor = this.options.appDescriptor?.anchor;
|
|
96
189
|
const flexSettings = this.rta.getFlexSettings();
|
|
97
190
|
const modifiedValue = {
|
|
98
191
|
reference: this.options.appDescriptor?.projectId,
|
|
@@ -101,16 +194,22 @@ sap.ui.define(["sap/ui/model/json/JSONModel", "../../i18n", "../command-executor
|
|
|
101
194
|
parameters: {
|
|
102
195
|
page: this.options.appDescriptor?.pageId,
|
|
103
196
|
entityPropertyChange: {
|
|
104
|
-
propertyPath: `${this.options.propertyPath}${
|
|
197
|
+
propertyPath: `${this.options.propertyPath}${id}`,
|
|
105
198
|
// e.g. 'content/body/sections/test'
|
|
106
199
|
operation: 'UPSERT',
|
|
107
200
|
propertyValue: {
|
|
108
201
|
template,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
202
|
+
...(this.options.type === 'tableColumn' ? {
|
|
203
|
+
header: 'New Column'
|
|
204
|
+
} : {
|
|
205
|
+
title: 'New Custom Section'
|
|
206
|
+
}),
|
|
207
|
+
...(anchor && {
|
|
208
|
+
position: {
|
|
209
|
+
placement: 'After',
|
|
210
|
+
anchor
|
|
211
|
+
}
|
|
212
|
+
})
|
|
114
213
|
}
|
|
115
214
|
}
|
|
116
215
|
}
|
|
@@ -14,9 +14,8 @@ import JSONModel from 'sap/ui/model/json/JSONModel';
|
|
|
14
14
|
/** sap.ui.rta */
|
|
15
15
|
import type RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
|
|
16
16
|
|
|
17
|
-
import { getResourceModel } from '../../i18n';
|
|
17
|
+
import { getResourceModel, getTextBundle, TextBundle } from '../../i18n';
|
|
18
18
|
import CommandExecutor from '../command-executor';
|
|
19
|
-
import { getFragments } from '../api-handler';
|
|
20
19
|
import BaseDialog from './BaseDialog.controller';
|
|
21
20
|
import { QuickActionTelemetryData } from '../../cpe/quick-actions/quick-action-definition';
|
|
22
21
|
import { MessageBarType, setApplicationRequiresReload } from '@sap-ux-private/control-property-editor-common';
|
|
@@ -25,22 +24,62 @@ import FlexCommand from 'sap/ui/rta/command/FlexCommand';
|
|
|
25
24
|
import { sendInfoCenterMessage } from '../../utils/info-center-message';
|
|
26
25
|
import { getError } from '../../utils/error';
|
|
27
26
|
import { PageDescriptorV4 } from './types';
|
|
27
|
+
import Input from 'sap/m/Input';
|
|
28
|
+
import { ValueState } from 'sap/ui/core/library';
|
|
29
|
+
import SimpleForm from 'sap/ui/layout/form';
|
|
30
|
+
import Control from 'sap/ui/core/Control';
|
|
31
|
+
import { getFragments } from '../api-handler';
|
|
28
32
|
|
|
29
33
|
export type AddFragmentModel = JSONModel & {
|
|
30
34
|
getProperty(sPath: '/title'): string;
|
|
31
35
|
getProperty(sPath: '/newFragmentName'): string;
|
|
36
|
+
getProperty(sPath: '/isCustomColumnFragment'): boolean;
|
|
32
37
|
};
|
|
33
38
|
|
|
34
39
|
export interface AddCustomFragmentOptions {
|
|
35
40
|
title: string;
|
|
36
41
|
propertyPath: string;
|
|
37
42
|
appDescriptor?: PageDescriptorV4;
|
|
43
|
+
validateId?: (id: string) => boolean;
|
|
44
|
+
type: 'section' | 'tableColumn';
|
|
45
|
+
availability?: 'Default' | 'Adaptation' | 'Hidden';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Validates Control ID input.
|
|
50
|
+
*
|
|
51
|
+
* @param input control of control ID to validate
|
|
52
|
+
* @param validateForDuplicateId custom validation function
|
|
53
|
+
* @return validation result
|
|
54
|
+
*/
|
|
55
|
+
function validateControlId(
|
|
56
|
+
input: Input,
|
|
57
|
+
resource: TextBundle,
|
|
58
|
+
identifier: 'Column' = 'Column',
|
|
59
|
+
validateForDuplicateId?: (id: string) => boolean
|
|
60
|
+
): { isValid: boolean; errorMessage: string } {
|
|
61
|
+
const id = input.getValue();
|
|
62
|
+
// Check if empty
|
|
63
|
+
if (!id || id.trim().length === 0) {
|
|
64
|
+
return { isValid: false, errorMessage: resource.getText('ID_REQUIRED', [identifier]) };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (typeof validateForDuplicateId === 'function' && !validateForDuplicateId?.(id)) {
|
|
68
|
+
return { isValid: false, errorMessage: resource.getText('GIVEN_ID_ALREADY_EXISTS', [identifier, id]) };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Check if starts with number
|
|
72
|
+
if (!/(^([A-Za-z_][-A-Za-z0-9_.:]*)$)/.test(id)) {
|
|
73
|
+
return { isValid: false, errorMessage: resource.getText('ID_INVALID_FORMAT', [identifier]) };
|
|
74
|
+
}
|
|
75
|
+
return { isValid: true, errorMessage: '' };
|
|
38
76
|
}
|
|
39
77
|
|
|
40
78
|
/**
|
|
41
79
|
* @namespace open.ux.preview.client.adp.controllers
|
|
42
80
|
*/
|
|
43
81
|
export default class AddCustomFragment extends BaseDialog<AddFragmentModel> {
|
|
82
|
+
private bundle: TextBundle;
|
|
44
83
|
constructor(
|
|
45
84
|
name: string,
|
|
46
85
|
overlays: UI5Element,
|
|
@@ -66,6 +105,7 @@ export default class AddCustomFragment extends BaseDialog<AddFragmentModel> {
|
|
|
66
105
|
this.dialog = dialog;
|
|
67
106
|
|
|
68
107
|
this.setEscapeHandler();
|
|
108
|
+
this.bundle = await getTextBundle();
|
|
69
109
|
await this.buildDialogData();
|
|
70
110
|
const resourceModel = await getResourceModel('open.ux.preview.client');
|
|
71
111
|
|
|
@@ -92,7 +132,7 @@ export default class AddCustomFragment extends BaseDialog<AddFragmentModel> {
|
|
|
92
132
|
CommunicationService.sendAction(setApplicationRequiresReload(true));
|
|
93
133
|
|
|
94
134
|
await sendInfoCenterMessage({
|
|
95
|
-
title: { key: 'ADP_ADD_FRAGMENT_DIALOG_TITLE' },
|
|
135
|
+
title: { key: this.options.title ?? 'ADP_ADD_FRAGMENT_DIALOG_TITLE' },
|
|
96
136
|
description: { key: 'ADP_ADD_FRAGMENT_NOTIFICATION', params: [fragmentName] },
|
|
97
137
|
type: MessageBarType.warning
|
|
98
138
|
});
|
|
@@ -104,24 +144,82 @@ export default class AddCustomFragment extends BaseDialog<AddFragmentModel> {
|
|
|
104
144
|
* Builds data that is used in the dialog
|
|
105
145
|
*/
|
|
106
146
|
async buildDialogData(): Promise<void> {
|
|
147
|
+
try {
|
|
148
|
+
let isCustomColumnFragment = false;
|
|
149
|
+
if (this.options.type === 'tableColumn') {
|
|
150
|
+
await this.addFragmentListToModel();
|
|
151
|
+
isCustomColumnFragment = true;
|
|
152
|
+
}
|
|
153
|
+
this.model.setProperty('/isCustomColumnFragment', isCustomColumnFragment);
|
|
154
|
+
} catch (e) {
|
|
155
|
+
const error = getError(e);
|
|
156
|
+
await sendInfoCenterMessage({
|
|
157
|
+
title: { key: this.options.title ?? 'ADP_ADD_FRAGMENT_DIALOG_TITLE' },
|
|
158
|
+
description: error.message,
|
|
159
|
+
type: MessageBarType.error
|
|
160
|
+
});
|
|
161
|
+
throw error;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
private async addFragmentListToModel(): Promise<void> {
|
|
107
165
|
try {
|
|
108
166
|
const { fragments } = await getFragments();
|
|
167
|
+
|
|
109
168
|
this.model.setProperty('/fragmentList', fragments);
|
|
110
169
|
} catch (e) {
|
|
111
170
|
const error = getError(e);
|
|
112
171
|
await sendInfoCenterMessage({
|
|
113
|
-
title: { key: '
|
|
172
|
+
title: { key: 'ADP_ADD_FRAGMENT_FAILURE_TITLE' },
|
|
114
173
|
description: error.message,
|
|
115
174
|
type: MessageBarType.error
|
|
116
175
|
});
|
|
117
176
|
throw error;
|
|
118
177
|
}
|
|
119
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Checks input values for duplicates and updates confirmation button state based on input validation states
|
|
181
|
+
*/
|
|
182
|
+
private updateFormState(): void {
|
|
183
|
+
const form = this.dialog.getContent()[0] as unknown as SimpleForm<Control[]>;
|
|
184
|
+
const formContent = form.getContent();
|
|
185
|
+
const inputs = formContent.filter((item) => item.isA('sap.m.Input')) as Input[];
|
|
186
|
+
|
|
187
|
+
const beginBtn = this.dialog.getBeginButton();
|
|
188
|
+
// Exclude the last input (display-only) from validation
|
|
189
|
+
// Only validate inputs that are visible and editable
|
|
190
|
+
const validatableInputs = inputs.filter((input) => input.getVisible() && input.getEditable());
|
|
191
|
+
beginBtn.setEnabled(validatableInputs.every((input) => input.getValueState() === ValueState.Success));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Handles id input change
|
|
196
|
+
*
|
|
197
|
+
* @param event Event
|
|
198
|
+
*/
|
|
199
|
+
onIdInputChange(event: Event): void {
|
|
200
|
+
// update model value
|
|
201
|
+
const input = event.getSource<Input>();
|
|
202
|
+
let modelValue: string | null = input.getValue();
|
|
203
|
+
if (modelValue.length < 1) {
|
|
204
|
+
modelValue = null;
|
|
205
|
+
}
|
|
206
|
+
this.model.setProperty('/id', modelValue);
|
|
207
|
+
const result = validateControlId(input, this.bundle, 'Column', this.options.validateId);
|
|
208
|
+
if (result.isValid) {
|
|
209
|
+
input.setValueState(ValueState.Success).setValueStateText('');
|
|
210
|
+
} else {
|
|
211
|
+
input.setValueState(ValueState.Error).setValueStateText(result.errorMessage);
|
|
212
|
+
}
|
|
213
|
+
this.updateFormState();
|
|
214
|
+
}
|
|
120
215
|
|
|
121
216
|
private async createAppDescriptorChangeForV4(templatePath: string) {
|
|
122
|
-
const
|
|
217
|
+
const id =
|
|
218
|
+
this.options.type === 'tableColumn'
|
|
219
|
+
? this.model.getProperty('/id')
|
|
220
|
+
: this.model.getProperty('/newFragmentName');
|
|
123
221
|
const template = `${this.options.appDescriptor?.projectId}.changes.${templatePath}`;
|
|
124
|
-
const
|
|
222
|
+
const anchor = this.options.appDescriptor?.anchor;
|
|
125
223
|
const flexSettings = this.rta.getFlexSettings();
|
|
126
224
|
const modifiedValue = {
|
|
127
225
|
reference: this.options.appDescriptor?.projectId,
|
|
@@ -130,15 +228,19 @@ export default class AddCustomFragment extends BaseDialog<AddFragmentModel> {
|
|
|
130
228
|
parameters: {
|
|
131
229
|
page: this.options.appDescriptor?.pageId,
|
|
132
230
|
entityPropertyChange: {
|
|
133
|
-
propertyPath: `${this.options.propertyPath}${
|
|
231
|
+
propertyPath: `${this.options.propertyPath}${id}`, // e.g. 'content/body/sections/test'
|
|
134
232
|
operation: 'UPSERT',
|
|
135
233
|
propertyValue: {
|
|
136
234
|
template,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
235
|
+
...(this.options.type === 'tableColumn'
|
|
236
|
+
? { header: 'New Column' }
|
|
237
|
+
: { title: 'New Custom Section' }),
|
|
238
|
+
...(anchor && {
|
|
239
|
+
position: {
|
|
240
|
+
placement: 'After',
|
|
241
|
+
anchor
|
|
242
|
+
}
|
|
243
|
+
})
|
|
142
244
|
}
|
|
143
245
|
}
|
|
144
246
|
}
|
|
@@ -14,7 +14,7 @@ sap.ui.define(["sap/ui/dt/OverlayRegistry", "../../dialog-factory", "../../../ut
|
|
|
14
14
|
const TableQuickActionDefinitionBase = ___table_quick_action_base["TableQuickActionDefinitionBase"];
|
|
15
15
|
const MDC_TABLE_TYPE = ___control_types["MDC_TABLE_TYPE"];
|
|
16
16
|
const isA = _____utils_core["isA"];
|
|
17
|
-
const
|
|
17
|
+
const getPropertyPath = ___utils["getPropertyPath"];
|
|
18
18
|
const CREATE_TABLE_ACTION = 'create-table-action';
|
|
19
19
|
const regexForAnnotationPath = /controlConfiguration\/(?:[^@]+\/)?@com\.sap\.vocabularies\.UI\.v1\.LineItem(?:#[^/]+)?\/actions\//;
|
|
20
20
|
|
|
@@ -40,7 +40,7 @@ sap.ui.define(["sap/ui/dt/OverlayRegistry", "../../dialog-factory", "../../../ut
|
|
|
40
40
|
const {
|
|
41
41
|
table
|
|
42
42
|
} = this.tableMap[path];
|
|
43
|
-
const propertyPath = `${
|
|
43
|
+
const propertyPath = `${getPropertyPath(table)}`;
|
|
44
44
|
if (!table || !propertyPath) {
|
|
45
45
|
return [];
|
|
46
46
|
}
|
|
@@ -14,7 +14,7 @@ import { isA } from '../../../utils/core';
|
|
|
14
14
|
import Table from 'sap/ui/mdc/Table';
|
|
15
15
|
import XMLView from 'sap/ui/core/mvc/XMLView';
|
|
16
16
|
import ActionToolbarAction from 'sap/ui/mdc/actiontoolbar/ActionToolbarAction';
|
|
17
|
-
import {
|
|
17
|
+
import { getPropertyPath } from './utils';
|
|
18
18
|
|
|
19
19
|
export const CREATE_TABLE_ACTION = 'create-table-action';
|
|
20
20
|
|
|
@@ -46,7 +46,7 @@ export class AddTableActionQuickAction extends TableQuickActionDefinitionBase im
|
|
|
46
46
|
|
|
47
47
|
async execute(path: string): Promise<FlexCommand[]> {
|
|
48
48
|
const { table } = this.tableMap[path];
|
|
49
|
-
const propertyPath = `${
|
|
49
|
+
const propertyPath = `${getPropertyPath(table)}`;
|
|
50
50
|
if (!table || !propertyPath) {
|
|
51
51
|
return [];
|
|
52
52
|
}
|
|
@@ -82,15 +82,13 @@ export class AddTableActionQuickAction extends TableQuickActionDefinitionBase im
|
|
|
82
82
|
}
|
|
83
83
|
if (
|
|
84
84
|
isA(MDC_TABLE_TYPE, table) &&
|
|
85
|
-
(table as Table)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.endsWith(`CustomAction::${actionId}`)
|
|
93
|
-
)
|
|
85
|
+
(table as Table).getActions().every(
|
|
86
|
+
(action) =>
|
|
87
|
+
!(action as ActionToolbarAction)
|
|
88
|
+
.getAction()
|
|
89
|
+
.getId()
|
|
90
|
+
.endsWith(`CustomAction::${actionId}`)
|
|
91
|
+
)
|
|
94
92
|
) {
|
|
95
93
|
return true;
|
|
96
94
|
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
sap.ui.define(["sap/ui/dt/OverlayRegistry", "../../dialog-factory", "../control-types", "../table-quick-action-base", "../dialog-enablement-validator", "../../../utils/fe-v4", "./utils", "../../../utils/version", "../../../utils/core"], function (OverlayRegistry, ____dialog_factory, ___control_types, ___table_quick_action_base, ___dialog_enablement_validator, _____utils_fe_v4, ___utils, _____utils_version, _____utils_core) {
|
|
4
|
+
"use strict";
|
|
5
|
+
|
|
6
|
+
const DialogFactory = ____dialog_factory["DialogFactory"];
|
|
7
|
+
const DialogNames = ____dialog_factory["DialogNames"];
|
|
8
|
+
const SMART_TABLE_TYPE = ___control_types["SMART_TABLE_TYPE"];
|
|
9
|
+
const GRID_TABLE_TYPE = ___control_types["GRID_TABLE_TYPE"];
|
|
10
|
+
const MDC_TABLE_TYPE = ___control_types["MDC_TABLE_TYPE"];
|
|
11
|
+
const TREE_TABLE_TYPE = ___control_types["TREE_TABLE_TYPE"];
|
|
12
|
+
const TableQuickActionDefinitionBase = ___table_quick_action_base["TableQuickActionDefinitionBase"];
|
|
13
|
+
const DIALOG_ENABLEMENT_VALIDATOR = ___dialog_enablement_validator["DIALOG_ENABLEMENT_VALIDATOR"];
|
|
14
|
+
const getV4AppComponent = _____utils_fe_v4["getV4AppComponent"];
|
|
15
|
+
const isMacroTable = _____utils_fe_v4["isMacroTable"];
|
|
16
|
+
const getLineItemAnnotation = ___utils["getLineItemAnnotation"];
|
|
17
|
+
const getPropertyPath = ___utils["getPropertyPath"];
|
|
18
|
+
const getUi5Version = _____utils_version["getUi5Version"];
|
|
19
|
+
const isLowerThanMinimalUi5Version = _____utils_version["isLowerThanMinimalUi5Version"];
|
|
20
|
+
const isA = _____utils_core["isA"];
|
|
21
|
+
const CREATE_TABLE_CUSTOM_COLUMN = 'create-table-custom-column';
|
|
22
|
+
const regexForAnnotationPath = /controlConfiguration\/(?:entity\/)?@com\.sap\.vocabularies\.UI\.v1\.LineItem(?:#[^/]+)?\/columns\//;
|
|
23
|
+
const CONTROL_TYPES = [SMART_TABLE_TYPE, MDC_TABLE_TYPE, TREE_TABLE_TYPE, GRID_TABLE_TYPE];
|
|
24
|
+
class AddTableCustomColumnQuickAction extends TableQuickActionDefinitionBase {
|
|
25
|
+
constructor(context) {
|
|
26
|
+
super(CREATE_TABLE_CUSTOM_COLUMN, CONTROL_TYPES, 'QUICK_ACTION_ADD_CUSTOM_TABLE_COLUMN', context, {
|
|
27
|
+
validateTableColumns: true
|
|
28
|
+
}, [DIALOG_ENABLEMENT_VALIDATOR]);
|
|
29
|
+
}
|
|
30
|
+
async initialize() {
|
|
31
|
+
this.pageId = this.context.view.getViewData()?.stableId.split('::').pop();
|
|
32
|
+
const version = await getUi5Version();
|
|
33
|
+
if (isLowerThanMinimalUi5Version(version, {
|
|
34
|
+
major: 1,
|
|
35
|
+
minor: 120
|
|
36
|
+
})) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await super.initialize();
|
|
40
|
+
}
|
|
41
|
+
async execute(path) {
|
|
42
|
+
const {
|
|
43
|
+
table
|
|
44
|
+
} = this.tableMap[path];
|
|
45
|
+
if (!table) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
if (table) {
|
|
49
|
+
const overlay = OverlayRegistry.getOverlay(table) || [];
|
|
50
|
+
const propertyPath = `${getPropertyPath(table, 'columns')}`;
|
|
51
|
+
const anchor = findAnchor(table);
|
|
52
|
+
await DialogFactory.createDialog(overlay, this.context.rta, DialogNames.ADD_CUSTOM_FRAGMENT, undefined, {
|
|
53
|
+
title: 'QUICK_ACTION_ADD_CUSTOM_TABLE_COLUMN',
|
|
54
|
+
type: 'tableColumn',
|
|
55
|
+
appDescriptor: {
|
|
56
|
+
appComponent: getV4AppComponent(this.context.view),
|
|
57
|
+
appType: 'fe-v4',
|
|
58
|
+
pageId: this.pageId,
|
|
59
|
+
projectId: this.context.flexSettings.projectId,
|
|
60
|
+
anchor
|
|
61
|
+
},
|
|
62
|
+
validateId: columnId => {
|
|
63
|
+
const customColumnInPending = [...this.context.changeService.getAllPendingConfigPropertyPath()].filter(path => regexForAnnotationPath.test(path));
|
|
64
|
+
const idInPendingChanges = customColumnInPending.includes(`${propertyPath}${columnId}`);
|
|
65
|
+
if (idInPendingChanges) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (isA(MDC_TABLE_TYPE, table) && table.getColumns().every(col => !col.getId().endsWith(`CustomColumn::${columnId}`))) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return false;
|
|
72
|
+
},
|
|
73
|
+
propertyPath
|
|
74
|
+
}, {
|
|
75
|
+
actionName: this.type,
|
|
76
|
+
telemetryEventIdentifier: this.getTelemetryIdentifier()
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function findAnchor(table) {
|
|
83
|
+
const macroTable = table.getParent();
|
|
84
|
+
let anchor = '';
|
|
85
|
+
if (isMacroTable(macroTable)) {
|
|
86
|
+
let metaPath = '';
|
|
87
|
+
if (macroTable.metaPath.includes('LineItem')) {
|
|
88
|
+
metaPath = macroTable.metaPath;
|
|
89
|
+
} else {
|
|
90
|
+
const segments = macroTable.metaPath.split('/');
|
|
91
|
+
segments.pop();
|
|
92
|
+
const path = segments.join('/');
|
|
93
|
+
metaPath = `${path}/${getLineItemAnnotation(macroTable)}`;
|
|
94
|
+
}
|
|
95
|
+
if (!metaPath) {
|
|
96
|
+
return '';
|
|
97
|
+
}
|
|
98
|
+
const columns = macroTable.getModel()?.getMetaModel()?.getObject(metaPath);
|
|
99
|
+
const filteredColumns = columns.filter(col => ['com.sap.vocabularies.UI.v1.DataField', 'com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation', 'com.sap.vocabularies.UI.v1.DataFieldForAnnotation'].includes(col.$Type) || 'com.sap.vocabularies.UI.v1.DataFieldForAction' === col.$Type && col.Inline);
|
|
100
|
+
const lastColumn = filteredColumns.at(-1);
|
|
101
|
+
if (!lastColumn) {
|
|
102
|
+
return '';
|
|
103
|
+
}
|
|
104
|
+
anchor = buildColumnAnchor(lastColumn);
|
|
105
|
+
}
|
|
106
|
+
return anchor;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Builds anchor string for different column types
|
|
111
|
+
* @param column - The column object from metadata
|
|
112
|
+
* @returns The anchor string for the column
|
|
113
|
+
*/
|
|
114
|
+
function buildColumnAnchor(column) {
|
|
115
|
+
if (column.$Type === 'com.sap.vocabularies.UI.v1.DataFieldForAction') {
|
|
116
|
+
return `DataFieldForAction::${column.Action}`;
|
|
117
|
+
}
|
|
118
|
+
if (column.$Type === 'com.sap.vocabularies.UI.v1.DataField') {
|
|
119
|
+
return `DataField::${column.Value?.$Path}`;
|
|
120
|
+
}
|
|
121
|
+
if (column.$Type === 'com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation') {
|
|
122
|
+
return `DataFieldForIntentBasedNavigation::${column.SemanticObject}::${column.Action}`;
|
|
123
|
+
}
|
|
124
|
+
if (column.$Type === 'com.sap.vocabularies.UI.v1.DataFieldForAnnotation') {
|
|
125
|
+
const annotationPath = column.Target?.$AnnotationPath;
|
|
126
|
+
if (!annotationPath) {
|
|
127
|
+
return '';
|
|
128
|
+
}
|
|
129
|
+
const annotation = annotationPath.split('.').pop();
|
|
130
|
+
return `DataFieldForAnnotation::${annotation?.split('#').join('::')}`;
|
|
131
|
+
}
|
|
132
|
+
return '';
|
|
133
|
+
}
|
|
134
|
+
var __exports = {
|
|
135
|
+
__esModule: true
|
|
136
|
+
};
|
|
137
|
+
__exports.CREATE_TABLE_CUSTOM_COLUMN = CREATE_TABLE_CUSTOM_COLUMN;
|
|
138
|
+
__exports.CONTROL_TYPES = CONTROL_TYPES;
|
|
139
|
+
__exports.AddTableCustomColumnQuickAction = AddTableCustomColumnQuickAction;
|
|
140
|
+
return __exports;
|
|
141
|
+
});
|
|
142
|
+
//# sourceMappingURL=create-table-custom-column-config-change.js.map
|