@sap-ux/preview-middleware 0.23.134 → 0.23.136

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/dist/client/adp/controllers/AddActionFragment.controller.js +1 -1
  2. package/dist/client/adp/controllers/AddActionFragment.controller.ts +1 -1
  3. package/dist/client/adp/controllers/AddCustomFragment.controller.js +111 -12
  4. package/dist/client/adp/controllers/AddCustomFragment.controller.ts +114 -12
  5. package/dist/client/adp/quick-actions/fe-v4/create-table-action-config-change.js +2 -2
  6. package/dist/client/adp/quick-actions/fe-v4/create-table-action-config-change.ts +9 -11
  7. package/dist/client/adp/quick-actions/fe-v4/create-table-custom-column-config-change.js +142 -0
  8. package/dist/client/adp/quick-actions/fe-v4/create-table-custom-column-config-change.ts +178 -0
  9. package/dist/client/adp/quick-actions/fe-v4/op-add-custom-section.js +2 -1
  10. package/dist/client/adp/quick-actions/fe-v4/op-add-custom-section.ts +2 -1
  11. package/dist/client/adp/quick-actions/fe-v4/registry.js +2 -2
  12. package/dist/client/adp/quick-actions/fe-v4/registry.ts +1 -1
  13. package/dist/client/adp/quick-actions/fe-v4/utils.js +26 -22
  14. package/dist/client/adp/quick-actions/fe-v4/utils.ts +34 -34
  15. package/dist/client/adp/quick-actions/table-quick-action-base.js +50 -6
  16. package/dist/client/adp/quick-actions/table-quick-action-base.ts +56 -5
  17. package/dist/client/adp/ui/AddCustomFragment.fragment.xml +6 -0
  18. package/dist/client/messagebundle.properties +5 -1
  19. package/dist/client/utils/fe-v4.js +12 -0
  20. package/dist/client/utils/fe-v4.ts +17 -0
  21. package/package.json +6 -6
  22. package/dist/client/adp/quick-actions/fe-v4/create-table-custom-column.js +0 -51
  23. 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('ACTION_ID_INVALID_FORMAT')
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('ACTION_ID_INVALID_FORMAT') };
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", "../api-handler", "./BaseDialog.controller", "open/ux/preview/client/thirdparty/@sap-ux-private/control-property-editor-common", "../../cpe/communication-service", "../../utils/info-center-message", "../../utils/error"], function (JSONModel, ____i18n, __CommandExecutor, ___api_handler, __BaseDialog, ___sap_ux_private_control_property_editor_common, ____cpe_communication_service, ____utils_info_center_message, ____utils_error) {
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: 'ADP_ADD_FRAGMENT_DIALOG_TITLE'
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 fragmentName = this.model.getProperty('/newFragmentName');
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 sectionId = this.options.appDescriptor?.anchor;
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}${fragmentName}`,
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
- title: 'New Custom Section',
110
- position: {
111
- placement: 'After',
112
- anchor: `${sectionId}`
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: 'ADP_ADD_FRAGMENT_DIALOG_TITLE' },
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 fragmentName = this.model.getProperty('/newFragmentName');
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 sectionId = this.options.appDescriptor?.anchor;
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}${fragmentName}`, // e.g. 'content/body/sections/test'
231
+ propertyPath: `${this.options.propertyPath}${id}`, // e.g. 'content/body/sections/test'
134
232
  operation: 'UPSERT',
135
233
  propertyValue: {
136
234
  template,
137
- title: 'New Custom Section',
138
- position: {
139
- placement: 'After',
140
- anchor: `${sectionId}`
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 getActionsPropertyPath = ___utils["getActionsPropertyPath"];
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 = `${getActionsPropertyPath(table)}`;
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 { getActionsPropertyPath } from './utils';
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 = `${getActionsPropertyPath(table)}`;
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
- .getActions()
87
- .every(
88
- (action) =>
89
- !(action as ActionToolbarAction)
90
- .getAction()
91
- .getId()
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