@sap-ux/preview-middleware 0.23.100 → 0.23.101

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.
@@ -38,14 +38,6 @@ sap.ui.define(["./BaseDialog.controller", "sap/ui/model/json/JSONModel", "../../
38
38
  };
39
39
  }
40
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
41
  // Check starts and only allowed characters
50
42
  if (!/(^([A-Za-z_][-A-Za-z0-9_.:]*)$)/.test(actionId)) {
51
43
  return {
@@ -186,7 +178,13 @@ sap.ui.define(["./BaseDialog.controller", "sap/ui/model/json/JSONModel", "../../
186
178
  press: this.options.controllerReference,
187
179
  visible: true,
188
180
  enabled: true,
189
- text: actionLabel
181
+ text: actionLabel,
182
+ ...(this.options.actionType === 'tableAction' ? {
183
+ requiresSelection: false
184
+ } : {}),
185
+ ...(this.options.position && {
186
+ position: this.options.position
187
+ })
190
188
  }
191
189
  }
192
190
  }
@@ -29,10 +29,15 @@ type AddActionFragmentsModel = JSONModel & {
29
29
  export interface AddActionOptions {
30
30
  name: string;
31
31
  propertyPath: string;
32
+ actionType: 'pageAction' | 'tableAction';
32
33
  title: string;
33
34
  controllerReference: string;
34
35
  appDescriptor?: PageDescriptorV4;
35
36
  validateActionId?: (actionId: string) => boolean;
37
+ position?: {
38
+ placement: 'Before' | 'After';
39
+ anchor: string;
40
+ };
36
41
  }
37
42
 
38
43
  /**
@@ -58,11 +63,6 @@ function validateActionId(
58
63
  return { isValid: false, errorMessage: resource.getText('ACTION_WITH_GIVEN_ID_ALREADY_EXISTS', [actionId]) };
59
64
  }
60
65
 
61
- // Check for spaces
62
- if (actionId.includes(' ')) {
63
- return { isValid: false, errorMessage: resource.getText('ACTION_ID_CANNOT_CONTAIN_SPACES') };
64
- }
65
-
66
66
  // Check starts and only allowed characters
67
67
  if (!/(^([A-Za-z_][-A-Za-z0-9_.:]*)$)/.test(actionId)) {
68
68
  return { isValid: false, errorMessage: resource.getText('ACTION_ID_INVALID_FORMAT') };
@@ -213,7 +213,9 @@ export default class AddActionFragment extends BaseDialog<AddActionFragmentsMode
213
213
  press: this.options.controllerReference,
214
214
  visible: true,
215
215
  enabled: true,
216
- text: actionLabel
216
+ text: actionLabel,
217
+ ...(this.options.actionType === 'tableAction' ? { requiresSelection: false } : {}),
218
+ ...(this.options.position && { position: this.options.position })
217
219
  }
218
220
  }
219
221
  }
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+
3
+ sap.ui.define(["sap/ui/dt/OverlayRegistry", "../../dialog-factory", "../../../utils/version", "../dialog-enablement-validator", "../../api-handler", "../../utils", "../../../utils/fe-v4", "../table-quick-action-base", "../control-types", "../../../utils/core", "./utils"], function (OverlayRegistry, ____dialog_factory, _____utils_version, ___dialog_enablement_validator, ____api_handler, ____utils, _____utils_fe_v4, ___table_quick_action_base, ___control_types, _____utils_core, ___utils) {
4
+ "use strict";
5
+
6
+ const DialogFactory = ____dialog_factory["DialogFactory"];
7
+ const DialogNames = ____dialog_factory["DialogNames"];
8
+ const getUi5Version = _____utils_version["getUi5Version"];
9
+ const isLowerThanMinimalUi5Version = _____utils_version["isLowerThanMinimalUi5Version"];
10
+ const DIALOG_ENABLEMENT_VALIDATOR = ___dialog_enablement_validator["DIALOG_ENABLEMENT_VALIDATOR"];
11
+ const getExistingController = ____api_handler["getExistingController"];
12
+ const getControllerInfoForControl = ____utils["getControllerInfoForControl"];
13
+ const getV4AppComponent = _____utils_fe_v4["getV4AppComponent"];
14
+ const TableQuickActionDefinitionBase = ___table_quick_action_base["TableQuickActionDefinitionBase"];
15
+ const MDC_TABLE_TYPE = ___control_types["MDC_TABLE_TYPE"];
16
+ const isA = _____utils_core["isA"];
17
+ const getActionsPropertyPath = ___utils["getActionsPropertyPath"];
18
+ const CREATE_TABLE_ACTION = 'create-table-action';
19
+ const regexForAnnotationPath = /controlConfiguration\/(?:[^@]+\/)?@com\.sap\.vocabularies\.UI\.v1\.LineItem(?:#[^/]+)?\/actions\//;
20
+
21
+ /**
22
+ * Quick Action for adding a custom page action.
23
+ */
24
+ class AddTableActionQuickAction extends TableQuickActionDefinitionBase {
25
+ constructor(context) {
26
+ super(CREATE_TABLE_ACTION, [MDC_TABLE_TYPE], 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION', context, undefined, [DIALOG_ENABLEMENT_VALIDATOR]);
27
+ }
28
+ async initialize() {
29
+ this.pageId = this.context.view.getViewData()?.stableId.split('::').pop();
30
+ const version = await getUi5Version();
31
+ if (isLowerThanMinimalUi5Version(version, {
32
+ major: 1,
33
+ minor: 120
34
+ })) {
35
+ return;
36
+ }
37
+ await super.initialize();
38
+ }
39
+ async execute(path) {
40
+ const {
41
+ table
42
+ } = this.tableMap[path];
43
+ const propertyPath = `${getActionsPropertyPath(table)}`;
44
+ if (!table || !propertyPath) {
45
+ return [];
46
+ }
47
+ if (table) {
48
+ const overlay = OverlayRegistry.getOverlay(table) || [];
49
+ const controlInfo = getControllerInfoForControl(table);
50
+ const data = await getExistingController(controlInfo.controllerName);
51
+ const controllerPath = data.controllerPathFromRoot.replaceAll('/', '.').replace(/\.[^.]+$/, '');
52
+ await DialogFactory.createDialog(overlay, this.context.rta, DialogNames.ADD_ACTION, undefined, {
53
+ title: 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION',
54
+ controllerReference: controllerPath ? `.extension.${controllerPath}.<methodName>` : '.extension.<ApplicationId.FolderName.ScriptFilename.methodName>',
55
+ actionType: 'tableAction',
56
+ appDescriptor: {
57
+ appComponent: getV4AppComponent(this.context.view),
58
+ appType: 'fe-v4',
59
+ pageId: this.pageId,
60
+ projectId: this.context.flexSettings.projectId
61
+ },
62
+ validateActionId: actionId => {
63
+ const actionPaths = [...this.context.changeService.getAllPendingConfigPropertyPath()].filter(path => regexForAnnotationPath.test(path));
64
+ const idInPendingChanges = actionPaths.includes(`${propertyPath}${actionId}`);
65
+ if (idInPendingChanges) {
66
+ return false;
67
+ }
68
+ if (isA(MDC_TABLE_TYPE, table) && table.getActions().every(action => !action.getAction().getId().endsWith(`CustomAction::${actionId}`))) {
69
+ return true;
70
+ }
71
+ return false;
72
+ },
73
+ position: calculatePosition(table, this.context.view),
74
+ propertyPath
75
+ }, {
76
+ actionName: this.type,
77
+ telemetryEventIdentifier: this.getTelemetryIdentifier()
78
+ });
79
+ }
80
+ return [];
81
+ }
82
+ }
83
+ function calculatePosition(table, view) {
84
+ const actions = table.getActions();
85
+ if (!actions.length) {
86
+ return undefined;
87
+ }
88
+ const annotationAction = actions.findIndex(action => action.getAction().getId().includes('::DataFieldForAction::'));
89
+ const customAction = actions.findIndex(action => action.getAction().getId().includes('::CustomAction::'));
90
+ if (annotationAction === -1 && customAction === -1) {
91
+ return undefined;
92
+ }
93
+ // determine the least index of either annotation or custom action
94
+ let actionIndex;
95
+ if (annotationAction === -1) {
96
+ actionIndex = customAction;
97
+ } else if (customAction === -1) {
98
+ actionIndex = annotationAction;
99
+ } else {
100
+ actionIndex = Math.min(annotationAction, customAction);
101
+ }
102
+ const actionToolBarAction = actions[actionIndex];
103
+ let anchor;
104
+ let action = actionToolBarAction?.getAction();
105
+ if (action) {
106
+ const localId = view.getLocalId(action.getId()) ?? '';
107
+ if (localId.includes('CustomAction::')) {
108
+ const str = localId.substring(Math.max(0, localId.lastIndexOf('CustomAction::')));
109
+ anchor = str.split('::').pop();
110
+ } else {
111
+ anchor = localId.substring(localId.lastIndexOf('DataFieldForAction::'));
112
+ }
113
+ }
114
+ if (!anchor) {
115
+ return undefined;
116
+ }
117
+ return {
118
+ placement: 'Before',
119
+ anchor
120
+ };
121
+ }
122
+ var __exports = {
123
+ __esModule: true
124
+ };
125
+ __exports.CREATE_TABLE_ACTION = CREATE_TABLE_ACTION;
126
+ __exports.AddTableActionQuickAction = AddTableActionQuickAction;
127
+ return __exports;
128
+ });
129
+ //# sourceMappingURL=create-table-action-config-change.js.map
@@ -0,0 +1,151 @@
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 { NestedQuickActionDefinition, QuickActionContext } from '../../../cpe/quick-actions/quick-action-definition';
6
+ import { getUi5Version, isLowerThanMinimalUi5Version } from '../../../utils/version';
7
+ import { DIALOG_ENABLEMENT_VALIDATOR } from '../dialog-enablement-validator';
8
+ import { getExistingController } from '../../api-handler';
9
+ import { getControllerInfoForControl } from '../../utils';
10
+ import { getV4AppComponent } from '../../../utils/fe-v4';
11
+ import { TableQuickActionDefinitionBase } from '../table-quick-action-base';
12
+ import { MDC_TABLE_TYPE } from '../control-types';
13
+ import { isA } from '../../../utils/core';
14
+ import Table from 'sap/ui/mdc/Table';
15
+ import XMLView from 'sap/ui/core/mvc/XMLView';
16
+ import ActionToolbarAction from 'sap/ui/mdc/actiontoolbar/ActionToolbarAction';
17
+ import { getActionsPropertyPath } from './utils';
18
+
19
+ export const CREATE_TABLE_ACTION = 'create-table-action';
20
+
21
+ interface ViewDataType {
22
+ stableId: string;
23
+ }
24
+ const regexForAnnotationPath =
25
+ /controlConfiguration\/(?:[^@]+\/)?@com\.sap\.vocabularies\.UI\.v1\.LineItem(?:#[^/]+)?\/actions\//;
26
+
27
+ /**
28
+ * Quick Action for adding a custom page action.
29
+ */
30
+ export class AddTableActionQuickAction extends TableQuickActionDefinitionBase implements NestedQuickActionDefinition {
31
+ protected pageId: string | undefined;
32
+ constructor(context: QuickActionContext) {
33
+ super(CREATE_TABLE_ACTION, [MDC_TABLE_TYPE], 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION', context, undefined, [
34
+ DIALOG_ENABLEMENT_VALIDATOR
35
+ ]);
36
+ }
37
+
38
+ async initialize(): Promise<void> {
39
+ this.pageId = (this.context.view.getViewData() as ViewDataType)?.stableId.split('::').pop() as string;
40
+ const version = await getUi5Version();
41
+ if (isLowerThanMinimalUi5Version(version, { major: 1, minor: 120 })) {
42
+ return;
43
+ }
44
+ await super.initialize();
45
+ }
46
+
47
+ async execute(path: string): Promise<FlexCommand[]> {
48
+ const { table } = this.tableMap[path];
49
+ const propertyPath = `${getActionsPropertyPath(table)}`;
50
+ if (!table || !propertyPath) {
51
+ return [];
52
+ }
53
+ if (table) {
54
+ const overlay = OverlayRegistry.getOverlay(table) || [];
55
+ const controlInfo = getControllerInfoForControl(table);
56
+ const data = await getExistingController(controlInfo.controllerName);
57
+ const controllerPath = data.controllerPathFromRoot.replaceAll('/', '.').replace(/\.[^.]+$/, '');
58
+ await DialogFactory.createDialog(
59
+ overlay,
60
+ this.context.rta,
61
+ DialogNames.ADD_ACTION,
62
+ undefined,
63
+ {
64
+ title: 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION',
65
+ controllerReference: controllerPath
66
+ ? `.extension.${controllerPath}.<methodName>`
67
+ : '.extension.<ApplicationId.FolderName.ScriptFilename.methodName>',
68
+ actionType: 'tableAction',
69
+ appDescriptor: {
70
+ appComponent: getV4AppComponent(this.context.view)!,
71
+ appType: 'fe-v4',
72
+ pageId: this.pageId!,
73
+ projectId: this.context.flexSettings.projectId
74
+ },
75
+ validateActionId: (actionId) => {
76
+ const actionPaths = [...this.context.changeService.getAllPendingConfigPropertyPath()].filter(
77
+ (path) => regexForAnnotationPath.test(path)
78
+ );
79
+ const idInPendingChanges = actionPaths.includes(`${propertyPath}${actionId}`);
80
+ if (idInPendingChanges) {
81
+ return false;
82
+ }
83
+ if (
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
+ )
94
+ ) {
95
+ return true;
96
+ }
97
+ return false;
98
+ },
99
+ position: calculatePosition(table as Table, this.context.view),
100
+ propertyPath
101
+ },
102
+ { actionName: this.type, telemetryEventIdentifier: this.getTelemetryIdentifier() }
103
+ );
104
+ }
105
+ return [];
106
+ }
107
+ }
108
+
109
+ function calculatePosition(table: Table, view: XMLView): { placement: 'Before' | 'After'; anchor: string } | undefined {
110
+ const actions = table.getActions() as ActionToolbarAction[];
111
+ if (!actions.length) {
112
+ return undefined;
113
+ }
114
+ const annotationAction = actions.findIndex((action) =>
115
+ action.getAction().getId().includes('::DataFieldForAction::')
116
+ );
117
+ const customAction = actions.findIndex((action) => action.getAction().getId().includes('::CustomAction::'));
118
+ if (annotationAction === -1 && customAction === -1) {
119
+ return undefined;
120
+ }
121
+ // determine the least index of either annotation or custom action
122
+ let actionIndex: number;
123
+ if (annotationAction === -1) {
124
+ actionIndex = customAction;
125
+ } else if (customAction === -1) {
126
+ actionIndex = annotationAction;
127
+ } else {
128
+ actionIndex = Math.min(annotationAction, customAction);
129
+ }
130
+ const actionToolBarAction = actions[actionIndex];
131
+ let anchor;
132
+ let action = actionToolBarAction?.getAction();
133
+
134
+ if (action) {
135
+ const localId = view.getLocalId(action.getId()) ?? '';
136
+ if (localId.includes('CustomAction::')) {
137
+ const str = localId.substring(Math.max(0, localId.lastIndexOf('CustomAction::')));
138
+ anchor = str.split('::').pop();
139
+ } else {
140
+ anchor = localId.substring(localId.lastIndexOf('DataFieldForAction::'));
141
+ }
142
+ }
143
+ if (!anchor) {
144
+ return undefined;
145
+ }
146
+
147
+ return {
148
+ placement: 'Before',
149
+ anchor
150
+ };
151
+ }
@@ -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", "./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) {
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", "./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", "./create-table-action-config-change"], 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, ___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, ___create_table_action_config_change) {
4
4
  "use strict";
5
5
 
6
6
  const QuickActionDefinitionRegistry = _____cpe_quick_actions_registry["QuickActionDefinitionRegistry"];
@@ -11,7 +11,6 @@ sap.ui.define(["../../../cpe/quick-actions/registry", "../common/add-controller-
11
11
  const AddCustomSectionQuickAction = ___op_add_custom_section["AddCustomSectionQuickAction"];
12
12
  const AddTableCustomColumnQuickAction = ___create_table_custom_column["AddTableCustomColumnQuickAction"];
13
13
  const AddPageActionQuickAction = ___create_page_action["AddPageActionQuickAction"];
14
- const AddTableActionQuickAction = ___create_table_action["AddTableActionQuickAction"];
15
14
  const EnableTableFilteringQuickAction = ___lr_enable_table_filtering["EnableTableFilteringQuickAction"];
16
15
  const ToggleSemanticDateRangeFilterBar = ___lr_enable_semantic_date_range_filter_bar["ToggleSemanticDateRangeFilterBar"];
17
16
  const EnableTableEmptyRowModeQuickAction = ___op_enable_empty_row_mode["EnableTableEmptyRowModeQuickAction"];
@@ -19,6 +18,7 @@ sap.ui.define(["../../../cpe/quick-actions/registry", "../common/add-controller-
19
18
  const EnableVariantManagementQuickAction = ___enable_variant_management["EnableVariantManagementQuickAction"];
20
19
  const AddNewSubpage = ___fe_v4_add_new_subpage["AddNewSubpage"];
21
20
  const ChangeTableActionsQuickAction = ___fe_v4_change_table_actions["ChangeTableActionsQuickAction"];
21
+ const AddTableActionQuickAction = ___create_table_action_config_change["AddTableActionQuickAction"];
22
22
  const LIST_REPORT_TYPE = 'sap.fe.templates.ListReport.ListReport';
23
23
  const OBJECT_PAGE_TYPE = 'sap.fe.templates.ObjectPage.ObjectPage';
24
24
 
@@ -11,7 +11,6 @@ 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
13
  import { AddPageActionQuickAction } from './create-page-action';
14
- import { AddTableActionQuickAction } from './create-table-action';
15
14
  import { EnableTableFilteringQuickAction } from './lr-enable-table-filtering';
16
15
  import { ToggleSemanticDateRangeFilterBar } from './lr-enable-semantic-date-range-filter-bar';
17
16
  import { EnableTableEmptyRowModeQuickAction } from './op-enable-empty-row-mode';
@@ -19,6 +18,7 @@ import { AddNewAnnotationFile } from '../common/add-new-annotation-file';
19
18
  import { EnableVariantManagementQuickAction } from './enable-variant-management';
20
19
  import { AddNewSubpage } from '../fe-v4/add-new-subpage';
21
20
  import { ChangeTableActionsQuickAction } from '../fe-v4/change-table-actions';
21
+ import { AddTableActionQuickAction } from './create-table-action-config-change';
22
22
 
23
23
  type PageName = 'listReport' | 'objectPage';
24
24
 
@@ -4,6 +4,7 @@ sap.ui.define(["../../../utils/core", "sap/ui/rta/command/CommandFactory", "../.
4
4
  "use strict";
5
5
 
6
6
  const getControlById = _____utils_core["getControlById"];
7
+ const isA = _____utils_core["isA"];
7
8
  const getV4AppComponent = _____utils_fe_v4["getV4AppComponent"];
8
9
  const getPageName = _____utils_fe_v4["getPageName"];
9
10
  const getReference = _____utils_fe_v4["getReference"];
@@ -64,11 +65,89 @@ sap.ui.define(["../../../utils/core", "sap/ui/rta/command/CommandFactory", "../.
64
65
  parts.push(PATTERN_SUFFIX);
65
66
  return parts.join('');
66
67
  }
68
+ /**
69
+ * Get LineItem annotation - tries to use design-time helper if available, falls back to local implementation.
70
+ *
71
+ * @param table - table control
72
+ * @returns LineItem annotation string
73
+ */
74
+ function getLineItemAnnotation(table) {
75
+ try {
76
+ const helper = sap.ui.require('sap/fe/macros/table/designtime/Table.designtime.helper');
77
+ if (helper && typeof helper.getLineItemAnnotation === 'function') {
78
+ return helper.getLineItemAnnotation(table);
79
+ }
80
+ } catch {
81
+ // Module not available or error occurred
82
+ }
83
+ return getLineItemAnnotationForTable(table);
84
+ }
85
+
86
+ /**
87
+ * Get property path for table action.
88
+ *
89
+ * @param table - table control
90
+ * @returns string
91
+ */
92
+ function getActionsPropertyPath(table) {
93
+ const macroTable = table.getParent();
94
+ const configPath = '';
95
+ if (macroTable && isA('sap.fe.macros.table.TableAPI', macroTable)) {
96
+ const lineItemAnnotation = getLineItemAnnotation(macroTable);
97
+ const navigationPath = macroTable.metaPath.split(macroTable.getProperty('contextPath'))[1];
98
+ if (!lineItemAnnotation) {
99
+ throw new Error('Line item annotation could not be determined for the table.');
100
+ }
101
+ if (navigationPath) {
102
+ return configPath.concat('controlConfiguration/', navigationPath.split('@')[0], lineItemAnnotation, '/actions/');
103
+ } else {
104
+ let contextString = macroTable.metaPath;
105
+ const firstSlash = contextString.indexOf('/');
106
+ if (firstSlash >= 0) {
107
+ contextString = contextString.substring(firstSlash + 1);
108
+ }
109
+ const secondSlash = contextString.indexOf('/');
110
+ if (secondSlash >= 0) {
111
+ contextString = contextString.substring(0, secondSlash);
112
+ }
113
+ return configPath.concat('controlConfiguration/', '/', contextString, '/', lineItemAnnotation, '/actions/');
114
+ }
115
+ }
116
+ return undefined;
117
+ }
118
+
119
+ /**
120
+ * Return the line item annotation that defines the table.
121
+ * This may come from a Presentation Variant, a Selection Presentation Variant or the default.
122
+ * @param table - The table control
123
+ * @returns The line item annotation used to define the table
124
+ */
125
+ function getLineItemAnnotationForTable(table) {
126
+ const presentation = table.getModel()?.getMetaModel()?.getObject(table.metaPath);
127
+ let lineItemAnnotation = '';
128
+ // default line item annotation
129
+ if (!presentation.Visualizations && !presentation.PresentationVariant) {
130
+ lineItemAnnotation = table.metaPath.split('/').pop();
131
+ } else if (presentation.Visualizations) {
132
+ lineItemAnnotation = presentation.Visualizations[0].$AnnotationPath;
133
+ } else if (presentation.PresentationVariant) {
134
+ if (presentation.PresentationVariant.Visualizations) {
135
+ lineItemAnnotation = presentation.PresentationVariant.Visualizations[0].$AnnotationPath;
136
+ } else {
137
+ const contextPath = table.metaPath.startsWith('/') ? table.metaPath.split('@')[0] : table.contextPath;
138
+ const pathForLineItems = contextPath + presentation.PresentationVariant.$Path;
139
+ const presentationVariantType = table.getModel()?.getMetaModel()?.getObject(pathForLineItems);
140
+ lineItemAnnotation = presentationVariantType.Visualizations[0].$AnnotationPath;
141
+ }
142
+ }
143
+ return lineItemAnnotation;
144
+ }
67
145
  var __exports = {
68
146
  __esModule: true
69
147
  };
70
148
  __exports.executeToggleAction = executeToggleAction;
71
149
  __exports.generateRoutePattern = generateRoutePattern;
150
+ __exports.getActionsPropertyPath = getActionsPropertyPath;
72
151
  return __exports;
73
152
  });
74
153
  //# sourceMappingURL=utils.js.map
@@ -1,8 +1,10 @@
1
- import { getControlById } from '../../../utils/core';
1
+ import { getControlById, isA } from '../../../utils/core';
2
2
  import type FlexCommand from 'sap/ui/rta/command/FlexCommand';
3
3
  import type { QuickActionContext } from '../../../cpe/quick-actions/quick-action-definition';
4
4
  import CommandFactory from 'sap/ui/rta/command/CommandFactory';
5
5
  import { getV4AppComponent, getPageName, getReference } from '../../../utils/fe-v4';
6
+ import TableAPI from 'sap/fe/macros/table/TableAPI';
7
+ import UI5Element from 'sap/ui/core/Element';
6
8
 
7
9
  export async function executeToggleAction(
8
10
  context: QuickActionContext,
@@ -62,11 +64,7 @@ const PATTERN_SUFFIX = ':?query:';
62
64
  * @param targetEntitySet navigation target entity set
63
65
  * @returns the generated pattern as string
64
66
  */
65
- export function generateRoutePattern(
66
- sourceRoutePattern: string,
67
- navProperty: string,
68
- targetEntitySet: string
69
- ): string {
67
+ export function generateRoutePattern(sourceRoutePattern: string, navProperty: string, targetEntitySet: string): string {
70
68
  const parts: string[] = [];
71
69
  const basePattern = sourceRoutePattern.replace(PATTERN_SUFFIX, '');
72
70
  if (basePattern) {
@@ -80,3 +78,93 @@ export function generateRoutePattern(
80
78
  parts.push(PATTERN_SUFFIX);
81
79
  return parts.join('');
82
80
  }
81
+
82
+ export type MacroTable = TableAPI & {
83
+ metaPath: string;
84
+ contextPath: string;
85
+ };
86
+
87
+ /**
88
+ * Get LineItem annotation - tries to use design-time helper if available, falls back to local implementation.
89
+ *
90
+ * @param table - table control
91
+ * @returns LineItem annotation string
92
+ */
93
+ function getLineItemAnnotation(table: MacroTable): string | undefined {
94
+ try {
95
+ const helper = sap.ui.require('sap/fe/macros/table/designtime/Table.designtime.helper');
96
+ if (helper && typeof helper.getLineItemAnnotation === 'function') {
97
+ return helper.getLineItemAnnotation(table);
98
+ }
99
+ } catch {
100
+ // Module not available or error occurred
101
+ }
102
+ return getLineItemAnnotationForTable(table);
103
+ }
104
+
105
+ /**
106
+ * Get property path for table action.
107
+ *
108
+ * @param table - table control
109
+ * @returns string
110
+ */
111
+ export function getActionsPropertyPath(table: UI5Element): string | undefined {
112
+ const macroTable = table.getParent();
113
+ const configPath = '';
114
+ if (macroTable && isA<MacroTable>('sap.fe.macros.table.TableAPI', macroTable)) {
115
+ const lineItemAnnotation = getLineItemAnnotation(macroTable);
116
+
117
+ const navigationPath = macroTable.metaPath.split(macroTable.getProperty('contextPath'))[1];
118
+ if (!lineItemAnnotation) {
119
+ throw new Error('Line item annotation could not be determined for the table.');
120
+ }
121
+ if (navigationPath) {
122
+ return configPath.concat(
123
+ 'controlConfiguration/',
124
+ navigationPath.split('@')[0],
125
+ lineItemAnnotation,
126
+ '/actions/'
127
+ );
128
+ } else {
129
+ let contextString = macroTable.metaPath;
130
+ const firstSlash = contextString.indexOf('/');
131
+ if (firstSlash >= 0) {
132
+ contextString = contextString.substring(firstSlash + 1);
133
+ }
134
+ const secondSlash = contextString.indexOf('/');
135
+ if (secondSlash >= 0) {
136
+ contextString = contextString.substring(0, secondSlash);
137
+ }
138
+ return configPath.concat('controlConfiguration/', '/', contextString, '/', lineItemAnnotation, '/actions/');
139
+ }
140
+ }
141
+ return undefined;
142
+ }
143
+
144
+ /**
145
+ * Return the line item annotation that defines the table.
146
+ * This may come from a Presentation Variant, a Selection Presentation Variant or the default.
147
+ * @param table - The table control
148
+ * @returns The line item annotation used to define the table
149
+ */
150
+ function getLineItemAnnotationForTable(table: MacroTable): string | undefined {
151
+ const presentation = table.getModel()?.getMetaModel()?.getObject(table.metaPath);
152
+
153
+ let lineItemAnnotation: string | undefined = '';
154
+ // default line item annotation
155
+ if (!presentation.Visualizations && !presentation.PresentationVariant) {
156
+ lineItemAnnotation = table.metaPath.split('/').pop();
157
+ } else if (presentation.Visualizations) {
158
+ lineItemAnnotation = presentation.Visualizations[0].$AnnotationPath;
159
+ } else if (presentation.PresentationVariant) {
160
+ if (presentation.PresentationVariant.Visualizations) {
161
+ lineItemAnnotation = presentation.PresentationVariant.Visualizations[0].$AnnotationPath;
162
+ } else {
163
+ const contextPath = table.metaPath.startsWith('/') ? table.metaPath.split('@')[0] : table.contextPath;
164
+ const pathForLineItems = contextPath + presentation.PresentationVariant.$Path;
165
+ const presentationVariantType = table.getModel()?.getMetaModel()?.getObject(pathForLineItems);
166
+ lineItemAnnotation = presentationVariantType.Visualizations[0].$AnnotationPath;
167
+ }
168
+ }
169
+ return lineItemAnnotation;
170
+ }
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.100",
12
+ "version": "0.23.101",
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.45",
30
31
  "@sap-ux/btp-utils": "1.1.6",
31
32
  "@sap-ux/control-property-editor-sources": "npm:@sap-ux/control-property-editor@0.7.9",
32
- "@sap-ux/adp-tooling": "0.18.45",
33
33
  "@sap-ux/logger": "0.8.0",
34
34
  "@sap-ux/project-access": "1.34.2",
35
- "@sap-ux/feature-toggle": "0.3.5",
36
35
  "@sap-ux/system-access": "0.6.43",
37
- "@sap-ux/i18n": "0.3.7"
36
+ "@sap-ux/i18n": "0.3.7",
37
+ "@sap-ux/feature-toggle": "0.3.5"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@sap-ux-private/playwright": "0.2.5",
@@ -53,7 +53,7 @@
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.12",
56
+ "@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@0.18.13",
57
57
  "@sap-ux/axios-extension": "1.25.7",
58
58
  "@sap-ux/store": "1.5.1",
59
59
  "@sap-ux/ui5-info": "0.13.8"
@@ -1,55 +0,0 @@
1
- "use strict";
2
-
3
- sap.ui.define(["sap/ui/dt/OverlayUtil", "../../../utils/core", "../../dialog-factory", "../dialog-enablement-validator", "../table-quick-action-base", "../control-types", "../fe-v2/create-table-custom-column"], function (OverlayUtil, _____utils_core, ____dialog_factory, ___dialog_enablement_validator, ___table_quick_action_base, ___control_types, ___fe_v2_create_table_custom_column) {
4
- "use strict";
5
-
6
- const getControlById = _____utils_core["getControlById"];
7
- const DialogFactory = ____dialog_factory["DialogFactory"];
8
- const DialogNames = ____dialog_factory["DialogNames"];
9
- const DIALOG_ENABLEMENT_VALIDATOR = ___dialog_enablement_validator["DIALOG_ENABLEMENT_VALIDATOR"];
10
- const TableQuickActionDefinitionBase = ___table_quick_action_base["TableQuickActionDefinitionBase"];
11
- const MDC_TABLE_TYPE = ___control_types["MDC_TABLE_TYPE"];
12
- const preprocessActionExecution = ___fe_v2_create_table_custom_column["preprocessActionExecution"];
13
- const CREATE_TABLE_ACTION = 'create-table-action';
14
-
15
- /**
16
- * Quick Action for creating table action.
17
- */
18
- class AddTableActionQuickAction extends TableQuickActionDefinitionBase {
19
- constructor(context) {
20
- super(CREATE_TABLE_ACTION, [MDC_TABLE_TYPE], 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION', context, undefined, [DIALOG_ENABLEMENT_VALIDATOR]);
21
- }
22
- async execute(path) {
23
- const {
24
- table,
25
- sectionInfo,
26
- iconTabBarFilterKey
27
- } = this.tableMap[path];
28
- if (!table) {
29
- return [];
30
- }
31
- preprocessActionExecution(table, sectionInfo, this.iconTabBar, iconTabBarFilterKey);
32
- const tableControl = getControlById(table.getId());
33
- const controlOverlay = OverlayUtil.getClosestOverlayFor(tableControl);
34
- if (controlOverlay) {
35
- controlOverlay.setSelected(true);
36
- await DialogFactory.createDialog(controlOverlay, this.context.rta, DialogNames.ADD_FRAGMENT, undefined, {
37
- aggregation: 'actions',
38
- defaultAggregationArrayIndex: 0,
39
- title: 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION'
40
- }, {
41
- actionName: this.type,
42
- telemetryEventIdentifier: this.getTelemetryIdentifier()
43
- });
44
- }
45
- return [];
46
- }
47
- }
48
- var __exports = {
49
- __esModule: true
50
- };
51
- __exports.CREATE_TABLE_ACTION = CREATE_TABLE_ACTION;
52
- __exports.AddTableActionQuickAction = AddTableActionQuickAction;
53
- return __exports;
54
- });
55
- //# sourceMappingURL=create-table-action.js.map
@@ -1,55 +0,0 @@
1
- import OverlayUtil from 'sap/ui/dt/OverlayUtil';
2
- import type FlexCommand from 'sap/ui/rta/command/FlexCommand';
3
-
4
- import {
5
- QuickActionContext,
6
- NestedQuickActionDefinition
7
- } from '../../../cpe/quick-actions/quick-action-definition';
8
- import { getControlById } from '../../../utils/core';
9
- import { DialogFactory, DialogNames } from '../../dialog-factory';
10
- import { DIALOG_ENABLEMENT_VALIDATOR } from '../dialog-enablement-validator';
11
- import { TableQuickActionDefinitionBase } from '../table-quick-action-base';
12
- import { MDC_TABLE_TYPE } from '../control-types';
13
- import { preprocessActionExecution } from '../fe-v2/create-table-custom-column';
14
-
15
- export const CREATE_TABLE_ACTION = 'create-table-action';
16
-
17
- /**
18
- * Quick Action for creating table action.
19
- */
20
- export class AddTableActionQuickAction extends TableQuickActionDefinitionBase implements NestedQuickActionDefinition {
21
- constructor(context: QuickActionContext) {
22
- super(CREATE_TABLE_ACTION, [MDC_TABLE_TYPE], 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION', context, undefined, [
23
- DIALOG_ENABLEMENT_VALIDATOR
24
- ]);
25
- }
26
-
27
- async execute(path: string): Promise<FlexCommand[]> {
28
- const { table, sectionInfo, iconTabBarFilterKey } = this.tableMap[path];
29
- if (!table) {
30
- return [];
31
- }
32
-
33
- preprocessActionExecution(table, sectionInfo, this.iconTabBar, iconTabBarFilterKey);
34
- const tableControl = getControlById(table.getId());
35
- const controlOverlay = OverlayUtil.getClosestOverlayFor(tableControl);
36
- if (controlOverlay) {
37
- controlOverlay.setSelected(true);
38
-
39
- await DialogFactory.createDialog(
40
- controlOverlay,
41
- this.context.rta,
42
- DialogNames.ADD_FRAGMENT,
43
- undefined,
44
- {
45
- aggregation: 'actions',
46
- defaultAggregationArrayIndex: 0,
47
- title: 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION'
48
- },
49
- { actionName: this.type, telemetryEventIdentifier: this.getTelemetryIdentifier() }
50
- );
51
- }
52
-
53
- return [];
54
- }
55
- }