From 740f4d9d5777cb379009389e1a33b53701492c9d Mon Sep 17 00:00:00 2001 From: vadson71 Date: Mon, 3 Feb 2025 12:57:26 +0200 Subject: [PATCH] fix: "add custom table action" quick action in ALP v4 projects with multiple toolbars in tables (#2826) * fix: bug fix * fix: cset added * fix: linter * fix: linter, jsdoc * fix: refactored v4 table related quick actions to reuse common table actions base class * fix: unit test fix * fix: cleanup --- .changeset/cyan-sloths-grow.md | 7 ++ .../adp/controllers/AddFragment.controller.ts | 2 +- .../fe-v4/change-table-columns.ts | 66 +++++++++++----- .../fe-v4/create-table-action.ts | 46 +++++------- .../fe-v4/lr-enable-table-filtering.ts | 23 +++--- .../fe-v4/table-quick-action-base.ts | 75 ------------------- .../AddFragment.controller.test.ts | 2 +- .../test/unit/adp/quick-actions/fe-v4.test.ts | 50 ++++++++----- 8 files changed, 112 insertions(+), 159 deletions(-) create mode 100644 .changeset/cyan-sloths-grow.md delete mode 100644 packages/preview-middleware-client/src/adp/quick-actions/fe-v4/table-quick-action-base.ts diff --git a/.changeset/cyan-sloths-grow.md b/.changeset/cyan-sloths-grow.md new file mode 100644 index 0000000000..7445ff1492 --- /dev/null +++ b/.changeset/cyan-sloths-grow.md @@ -0,0 +1,7 @@ +--- +'@sap-ux-private/preview-middleware-client': patch +'@sap-ux/preview-middleware': patch +--- + +fix: CPE Quick action bug fix in ALP v4 projects. Add Custom Table Action worked incorrectly on Analytical Pages with multiple action toolbars in charts and tables. +Some V4 Quick Action code refactoring to optimize diff --git a/packages/preview-middleware-client/src/adp/controllers/AddFragment.controller.ts b/packages/preview-middleware-client/src/adp/controllers/AddFragment.controller.ts index 392a0b69d0..44711b7071 100644 --- a/packages/preview-middleware-client/src/adp/controllers/AddFragment.controller.ts +++ b/packages/preview-middleware-client/src/adp/controllers/AddFragment.controller.ts @@ -264,7 +264,7 @@ export default class AddFragment extends BaseDialog { targetAggregation === 'columns' ) { return 'ANALYTICAL_TABLE_COLUMN'; - } else if (currentControlName === 'sap.ui.mdc.ActionToolbar' && targetAggregation === 'actions') { + } else if (currentControlName === 'sap.ui.mdc.Table' && targetAggregation === 'actions') { return 'TABLE_ACTION'; } return ''; diff --git a/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/change-table-columns.ts b/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/change-table-columns.ts index 1fd9826019..a2c0fbeaa4 100644 --- a/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/change-table-columns.ts +++ b/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/change-table-columns.ts @@ -2,15 +2,15 @@ import OverlayUtil from 'sap/ui/dt/OverlayUtil'; import FlexCommand from 'sap/ui/rta/command/FlexCommand'; import FlexRuntimeInfoAPI from 'sap/ui/fl/apply/api/FlexRuntimeInfoAPI'; import { QuickActionContext, NestedQuickActionDefinition } from '../../../cpe/quick-actions/quick-action-definition'; -import { getRelevantControlFromActivePage } from '../../../cpe/quick-actions/utils'; import { getControlById } from '../../../utils/core'; -import { TableQuickActionDefinitionBase } from './table-quick-action-base'; +import { TableQuickActionDefinitionBase } from '../table-quick-action-base'; import { MDC_TABLE_TYPE } from '../control-types'; import { DIALOG_ENABLEMENT_VALIDATOR } from '../dialog-enablement-validator'; +import { getRelevantControlFromActivePage } from '../../../cpe/quick-actions/utils'; +import Table from 'sap/ui/mdc/Table'; export const CHANGE_TABLE_COLUMNS = 'change-table-columns'; const ACTION_ID = 'CTX_SETTINGS0'; -const CONTROL_TYPE = 'sap.ui.mdc.Table'; /** * Quick Action for changing table columns. @@ -25,24 +25,50 @@ export class ChangeTableColumnsQuickAction ]); } - async execute(path: string): Promise { - const index = this.tableMap[path]; - const smartTables = getRelevantControlFromActivePage(this.context.controlIndex, this.context.view, [ - CONTROL_TYPE - ]); - for (let i = 0; i < smartTables.length; i++) { - if (i === index) { - const section = getControlById(smartTables[i].getId()); - const controlOverlay = OverlayUtil.getClosestOverlayFor(section); - if (controlOverlay) { - controlOverlay.setSelected(true); - } - const hasVariantManagement = FlexRuntimeInfoAPI.hasVariantManagement({ element: smartTables[i] }); - if (!hasVariantManagement) { - continue; - } - await this.context.actionService.execute(smartTables[i].getId(), ACTION_ID); + async initialize(): Promise { + for (const smartTable of getRelevantControlFromActivePage( + this.context.controlIndex, + this.context.view, + this.controlTypes + )) { + const hasVariantManagement = FlexRuntimeInfoAPI.hasVariantManagement({ element: smartTable }); + if (!hasVariantManagement) { + continue; } + + const actions = await this.context.actionService.get(smartTable.getId()); + const changeColumnAction = actions.find((action) => action.id === ACTION_ID); + if (changeColumnAction) { + this.children.push({ + label: `'${(smartTable as Table).getHeader()}' table`, + enabled: true, + children: [] + }); + this.tableMap[`${this.children.length - 1}`] = { + table: smartTable, + tableUpdateEventAttachedOnce: false + }; + } + } + + if (this.children.length > 0) { + this.isApplicable = true; + } + } + + async execute(path: string): Promise { + const { table } = this.tableMap[path]; + if (!table) { + return []; + } + const tableControl = getControlById(table.getId()); + const controlOverlay = OverlayUtil.getClosestOverlayFor(tableControl); + if (controlOverlay) { + controlOverlay.setSelected(true); + } + const hasVariantManagement = FlexRuntimeInfoAPI.hasVariantManagement({ element: table }); + if (hasVariantManagement) { + await this.context.actionService.execute(table.getId(), ACTION_ID); } return []; diff --git a/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/create-table-action.ts b/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/create-table-action.ts index 2efa385da3..cc93a96c57 100644 --- a/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/create-table-action.ts +++ b/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/create-table-action.ts @@ -2,51 +2,41 @@ import OverlayUtil from 'sap/ui/dt/OverlayUtil'; import type FlexCommand from 'sap/ui/rta/command/FlexCommand'; import { QuickActionContext, NestedQuickActionDefinition } from '../../../cpe/quick-actions/quick-action-definition'; -import { getRelevantControlFromActivePage } from '../../../cpe/quick-actions/utils'; import { getControlById } from '../../../utils/core'; import { DialogFactory, DialogNames } from '../../dialog-factory'; import { DIALOG_ENABLEMENT_VALIDATOR } from '../dialog-enablement-validator'; -import { TableQuickActionDefinitionBase } from './table-quick-action-base'; +import { TableQuickActionDefinitionBase } from '../table-quick-action-base'; import { MDC_TABLE_TYPE } from '../control-types'; +import { preprocessActionExecution } from '../fe-v2/create-table-custom-column'; export const CREATE_TABLE_ACTION = 'create_table_action'; -const TOOLBAR_ACTION = 'sap.ui.mdc.ActionToolbar'; /** * Quick Action for creating table action. */ export class AddTableActionQuickAction extends TableQuickActionDefinitionBase implements NestedQuickActionDefinition { constructor(context: QuickActionContext) { - super(CREATE_TABLE_ACTION, [MDC_TABLE_TYPE], 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION', context, true, [ + super(CREATE_TABLE_ACTION, [MDC_TABLE_TYPE], 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION', context, undefined, [ DIALOG_ENABLEMENT_VALIDATOR ]); } async execute(path: string): Promise { - const index = this.tableMap[path]; - const smartTablesToolbarAction = getRelevantControlFromActivePage( - this.context.controlIndex, - this.context.view, - [TOOLBAR_ACTION] - ); - for (let i = 0; i < smartTablesToolbarAction.length; i++) { - if (i === index) { - const section = getControlById(smartTablesToolbarAction[i].getId()); - const controlOverlay = OverlayUtil.getClosestOverlayFor(section); - if (controlOverlay) { - controlOverlay.setSelected(true); - await DialogFactory.createDialog( - controlOverlay, - this.context.rta, - DialogNames.ADD_FRAGMENT, - undefined, - { - aggregation: 'actions', - title: 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION' - } - ); - } - } + const { table, sectionInfo, iconTabBarFilterKey } = this.tableMap[path]; + if (!table) { + return []; + } + + preprocessActionExecution(table, sectionInfo, this.iconTabBar, iconTabBarFilterKey); + const tableControl = getControlById(table.getId()); + const controlOverlay = OverlayUtil.getClosestOverlayFor(tableControl); + if (controlOverlay) { + controlOverlay.setSelected(true); + + await DialogFactory.createDialog(controlOverlay, this.context.rta, DialogNames.ADD_FRAGMENT, undefined, { + aggregation: 'actions', + title: 'QUICK_ACTION_ADD_CUSTOM_TABLE_ACTION' + }); } return []; diff --git a/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/lr-enable-table-filtering.ts b/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/lr-enable-table-filtering.ts index 4b5f53a5e7..939f51ce6a 100644 --- a/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/lr-enable-table-filtering.ts +++ b/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/lr-enable-table-filtering.ts @@ -2,7 +2,7 @@ import FlexCommand from 'sap/ui/rta/command/FlexCommand'; import { NestedQuickActionDefinition, QuickActionContext } from '../../../cpe/quick-actions/quick-action-definition'; import Table from 'sap/ui/mdc/Table'; -import { TableQuickActionDefinitionBase } from './table-quick-action-base'; +import { TableQuickActionDefinitionBase } from '../table-quick-action-base'; import { getRelevantControlFromActivePage } from '../../../cpe/quick-actions/utils'; import { createManifestPropertyChange } from '../../../utils/fe-v4'; import { getUi5Version, isLowerThanMinimalUi5Version } from '../../../utils/version'; @@ -38,7 +38,7 @@ export class EnableTableFilteringQuickAction } const tooltipText = this.context.resourceBundle.getText('TABLE_FILTERING_CHANGE_HAS_ALREADY_BEEN_MADE'); - let index = 0; + for (const smartTable of getRelevantControlFromActivePage(this.context.controlIndex, this.context.view, [ MDC_TABLE_TYPE ])) { @@ -54,27 +54,22 @@ export class EnableTableFilteringQuickAction tooltip: isFilterEnabled ? tooltipText : undefined, children: [] }); - this.tableMap[`${this.children.length - 1}`] = index; - index++; + this.tableMap[`${this.children.length - 1}`] = { + table: smartTable, + tableUpdateEventAttachedOnce: false + }; } if (this.children.length > 0) { this.isApplicable = true; } - - return Promise.resolve(); } async execute(path: string): Promise { const { flexSettings } = this.context; - const index = this.tableMap[path]; - - const smartTables = getRelevantControlFromActivePage(this.context.controlIndex, this.context.view, [ - MDC_TABLE_TYPE - ]); + const { table } = this.tableMap[path]; - const modifiedControl = smartTables[index]; - if (!modifiedControl) { + if (!table) { return []; } const propertyChange = { @@ -86,7 +81,7 @@ export class EnableTableFilteringQuickAction aggregate: true } }; - const command = await createManifestPropertyChange(modifiedControl, flexSettings, propertyChange); + const command = await createManifestPropertyChange(table, flexSettings, propertyChange); if (command) { return [command]; } else { diff --git a/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/table-quick-action-base.ts b/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/table-quick-action-base.ts deleted file mode 100644 index c0ef815771..0000000000 --- a/packages/preview-middleware-client/src/adp/quick-actions/fe-v4/table-quick-action-base.ts +++ /dev/null @@ -1,75 +0,0 @@ -import Table from 'sap/ui/mdc/Table'; -import FlexRuntimeInfoAPI from 'sap/ui/fl/apply/api/FlexRuntimeInfoAPI'; - -import type { NestedQuickActionChild, NestedQuickAction } from '@sap-ux-private/control-property-editor-common'; -import { NESTED_QUICK_ACTION_KIND } from '@sap-ux-private/control-property-editor-common'; - -import { QuickActionContext } from '../../../cpe/quick-actions/quick-action-definition'; -import { getRelevantControlFromActivePage } from '../../../cpe/quick-actions/utils'; -import { EnablementValidator } from '../enablement-validator'; -import { QuickActionDefinitionBase } from '../quick-action-base'; - -const ACTION_ID = 'CTX_SETTINGS0'; - -export abstract class TableQuickActionDefinitionBase extends QuickActionDefinitionBase< - typeof NESTED_QUICK_ACTION_KIND -> { - isApplicable = false; - - isClearButtonEnabled = false; - children: NestedQuickActionChild[] = []; - tableMap: Record = {}; - constructor( - public readonly type: string, - protected readonly controlTypes: string[], - protected readonly defaultTextKey: string, - protected readonly context: QuickActionContext, - protected readonly isSkipVariantManagementCheck?: boolean, - protected readonly enablementValidators: EnablementValidator[] = [] - ) { - super(type, NESTED_QUICK_ACTION_KIND, defaultTextKey, context, enablementValidators); - } - - async initialize(): Promise { - let index = 0; - for (const smartTable of getRelevantControlFromActivePage( - this.context.controlIndex, - this.context.view, - this.controlTypes - )) { - if (!this.isSkipVariantManagementCheck) { - const hasVariantManagement = FlexRuntimeInfoAPI.hasVariantManagement({ element: smartTable }); - if (!hasVariantManagement) { - continue; - } - } - - const actions = await this.context.actionService.get(smartTable.getId()); - const changeColumnAction = actions.find((action) => action.id === ACTION_ID); - if (changeColumnAction) { - this.children.push({ - label: `'${(smartTable as Table).getHeader()}' table`, - enabled: true, - children: [] - }); - this.tableMap[`${this.children.length - 1}`] = index; - index++; - } - } - - if (this.children.length > 0) { - this.isApplicable = true; - } - } - - getActionObject(): NestedQuickAction { - return { - kind: NESTED_QUICK_ACTION_KIND, - id: this.id, - enabled: !this.isDisabled, - tooltip: this.tooltip, - title: this.context.resourceBundle.getText(this.textKey), - children: this.children - }; - } -} diff --git a/packages/preview-middleware-client/test/unit/adp/controllers/AddFragment.controller.test.ts b/packages/preview-middleware-client/test/unit/adp/controllers/AddFragment.controller.test.ts index 88d1eff4d6..14cc05247e 100644 --- a/packages/preview-middleware-client/test/unit/adp/controllers/AddFragment.controller.test.ts +++ b/packages/preview-middleware-client/test/unit/adp/controllers/AddFragment.controller.test.ts @@ -1247,7 +1247,7 @@ describe('AddFragment', () => { jest.spyOn(ControlUtils, 'getRuntimeControl').mockReturnValue({ getMetadata: jest.fn().mockReturnValue({ getAllAggregations: jest.fn().mockReturnValue({}), - getName: jest.fn().mockReturnValue('sap.ui.mdc.ActionToolbar') + getName: jest.fn().mockReturnValue('sap.ui.mdc.Table') }) } as unknown as ManagedObject); diff --git a/packages/preview-middleware-client/test/unit/adp/quick-actions/fe-v4.test.ts b/packages/preview-middleware-client/test/unit/adp/quick-actions/fe-v4.test.ts index c2498aef55..29d5861a76 100644 --- a/packages/preview-middleware-client/test/unit/adp/quick-actions/fe-v4.test.ts +++ b/packages/preview-middleware-client/test/unit/adp/quick-actions/fe-v4.test.ts @@ -674,19 +674,6 @@ describe('FE V4 quick actions', () => { }; } - if (id == 'ToolbarAction') { - return { - isA: (type: string) => type === 'sap.ui.mdc.ActionToolbar', - getHeader: () => 'MyTable', - getId: () => id, - getDomRef: () => ({ - scrollIntoView - }), - getParent: () => pageView, - getBusy: () => false - }; - } - if (id == 'NavContainer') { const container = new NavContainer(); const component = new TemplateComponentMock(); @@ -745,11 +732,6 @@ describe('FE V4 quick actions', () => { controlId: 'Table' } as any ], - 'sap.ui.mdc.ActionToolbar': [ - { - controlId: 'ToolbarAction' - } as any - ], 'sap.m.NavContainer': [ { controlId: 'NavContainer' @@ -802,7 +784,7 @@ describe('FE V4 quick actions', () => { describe('create table custom column', () => { test('initialize and execute action (%s)', async () => { const pageView = new XMLView(); - jest.spyOn(FlexRuntimeInfoAPI, 'hasVariantManagement').mockReturnValue(true); + jest.spyOn(FlexRuntimeInfoAPI, 'hasVariantManagement').mockReturnValue(false); const scrollIntoView = jest.fn(); const appComponent = new AppComponentMock(); const component = new TemplateComponentMock(); @@ -889,6 +871,20 @@ describe('FE V4 quick actions', () => { } ], 'enabled': true, + 'id': 'listReport0-create_table_action', + 'kind': 'nested', + 'title': 'Add Custom Table Action', + 'tooltip': undefined + }, + { + 'children': [ + { + 'children': [], + 'enabled': true, + 'label': `'MyTable' table` + } + ], + 'enabled': true, 'id': 'listReport0-create-table-custom-column', 'kind': 'nested', 'title': 'Add Custom Table Column' @@ -1035,7 +1031,21 @@ describe('FE V4 quick actions', () => { 'children': [ { 'children': [], - enabled: true, + 'enabled': true, + 'label': `'MyTable' table` + } + ], + 'enabled': true, + 'id': 'listReport0-create_table_action', + 'kind': 'nested', + 'title': 'Add Custom Table Action', + 'tooltip': undefined + }, + { + 'children': [ + { + 'children': [], + 'enabled': true, 'label': `'MyTable' table` } ],