Skip to content

Commit ee1796f

Browse files
authored
fix(VariantManagement): update "Manage Views" dialog to latest specs (#8080)
Implements focus behavior when deleting rows and adds a IllustratedMessage when no rows (views) are defined. Fixes #8079
1 parent df00067 commit ee1796f

File tree

3 files changed

+62
-15
lines changed

3 files changed

+62
-15
lines changed

packages/main/src/components/VariantManagement/ManageViewsDialog.tsx

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import BarDesign from '@ui5/webcomponents/dist/types/BarDesign.js';
22
import ButtonDesign from '@ui5/webcomponents/dist/types/ButtonDesign.js';
33
import TableOverflowMode from '@ui5/webcomponents/dist/types/TableOverflowMode.js';
44
import { getScopedVarName } from '@ui5/webcomponents-base/dist/CustomElementsScope.js';
5+
import { isPhone as getIsPhone } from '@ui5/webcomponents-base/dist/Device.js';
6+
import NoEntriesIllu from '@ui5/webcomponents-fiori/dist/illustrations/NoEntries.js';
57
import searchIcon from '@ui5/webcomponents-icons/dist/search.js';
8+
import type { Ui5DomRef } from '@ui5/webcomponents-react-base';
69
import { enrichEventWithDetails, useI18nBundle, useStylesheet } from '@ui5/webcomponents-react-base';
710
import type { MouseEventHandler, ReactElement } from 'react';
811
import { Children, isValidElement, useEffect, useId, useRef, useState } from 'react';
@@ -13,6 +16,8 @@ import {
1316
CANCEL,
1417
CREATED_BY,
1518
DEFAULT,
19+
NO_VIEWS_DEFINED_TITLE,
20+
NO_VIEWS_DEFINED_SUBTITLE,
1621
MANAGE_VIEWS,
1722
SAVE,
1823
SEARCH,
@@ -22,15 +27,18 @@ import {
2227
import type { CommonProps } from '../../types/CommonProps.js';
2328
import { Bar } from '../../webComponents/Bar/index.js';
2429
import { Button } from '../../webComponents/Button/index.js';
30+
import type { ButtonDomRef } from '../../webComponents/Button/index.js';
2531
import type { DialogPropTypes } from '../../webComponents/Dialog/index.js';
2632
import { Dialog } from '../../webComponents/Dialog/index.js';
2733
import { Icon } from '../../webComponents/Icon/index.js';
34+
import { IllustratedMessage } from '../../webComponents/IllustratedMessage/index.js';
2835
import type { InputDomRef } from '../../webComponents/Input/index.js';
2936
import { Input } from '../../webComponents/Input/index.js';
3037
import { Table } from '../../webComponents/Table/index.js';
31-
import type { TablePropTypes } from '../../webComponents/Table/index.js';
38+
import type { TableDomRef, TablePropTypes } from '../../webComponents/Table/index.js';
3239
import { TableHeaderCell } from '../../webComponents/TableHeaderCell/index.js';
3340
import { TableHeaderRow } from '../../webComponents/TableHeaderRow/index.js';
41+
import type { TableRowDomRef } from '../../webComponents/TableRow/index.js';
3442
import { FlexBox } from '../FlexBox/index.js';
3543
import type { VariantItemPropTypes } from '../VariantItem/index.js';
3644
import { classNames, styleData } from './ManageViewsDialog.module.css.js';
@@ -59,6 +67,8 @@ export interface ManageViewsDialogPropTypes {
5967
onManageViewsCancel?: VariantManagementPropTypes['onManageViewsCancel'];
6068
}
6169

70+
const isPhone = getIsPhone();
71+
6272
export const ManageViewsDialog = (props: ManageViewsDialogPropTypes) => {
6373
const {
6474
children,
@@ -74,6 +84,8 @@ export const ManageViewsDialog = (props: ManageViewsDialogPropTypes) => {
7484
} = props;
7585
const uniqueId = useId();
7686
const i18nBundle = useI18nBundle('@ui5/webcomponents-react');
87+
const tableRef = useRef<TableDomRef>(null);
88+
const cancelBtnRef = useRef<ButtonDomRef>(null);
7789
const cancelText = i18nBundle.getText(CANCEL);
7890
const saveText = i18nBundle.getText(SAVE);
7991
const viewHeaderText = i18nBundle.getText(VIEW);
@@ -158,18 +170,21 @@ export const ManageViewsDialog = (props: ManageViewsDialogPropTypes) => {
158170
};
159171
const deletedTableRows = useRef(new Set([]));
160172
const handleDelete: TablePropTypes['onRowActionClick'] = (e) => {
161-
const variantChild = e.detail.row.dataset.id;
173+
const { nextElementSibling, previousElementSibling, dataset } = e.detail.row;
174+
const variantChild = dataset.id;
175+
162176
deletedTableRows.current.add(variantChild);
163-
setChildrenProps((prev) =>
164-
prev
165-
.filter((item) => item.children !== variantChild)
166-
.map((item) => {
167-
if (Object.prototype.hasOwnProperty.call(changedTableRows.current, item.children)) {
168-
return { ...item, ...changedTableRows.current[item.children] };
169-
}
170-
return item;
171-
}),
172-
);
177+
let nextFocusElement: Ui5DomRef | null = null;
178+
if (nextElementSibling?.hasAttribute('ui5-table-row')) {
179+
nextFocusElement = nextElementSibling as TableRowDomRef;
180+
} else if (previousElementSibling?.hasAttribute('ui5-table-row')) {
181+
nextFocusElement = previousElementSibling as TableRowDomRef;
182+
} else {
183+
nextFocusElement = cancelBtnRef.current;
184+
}
185+
void nextFocusElement?.focus();
186+
187+
setChildrenProps((prev) => prev.filter((item) => item.children !== variantChild));
173188
};
174189

175190
const handleSave = (e) => {
@@ -222,6 +237,7 @@ export const ManageViewsDialog = (props: ManageViewsDialogPropTypes) => {
222237
return (
223238
<Dialog
224239
open
240+
stretch={isPhone}
225241
className={classNames.manageViewsDialog}
226242
data-component-name="VariantManagementManageViewsDialog"
227243
onClose={onAfterClose}
@@ -255,7 +271,7 @@ export const ManageViewsDialog = (props: ManageViewsDialogPropTypes) => {
255271
<Button design={ButtonDesign.Emphasized} onClick={handleSave}>
256272
{saveText}
257273
</Button>
258-
<Button design={ButtonDesign.Transparent} onClick={handleCancel}>
274+
<Button design={ButtonDesign.Transparent} onClick={handleCancel} ref={cancelBtnRef}>
259275
{cancelText}
260276
</Button>
261277
</>
@@ -264,10 +280,19 @@ export const ManageViewsDialog = (props: ManageViewsDialogPropTypes) => {
264280
}
265281
>
266282
<Table
283+
ref={tableRef}
267284
headerRow={headerRow}
268285
overflowMode={TableOverflowMode.Popin}
269286
rowActionCount={1}
270287
onRowActionClick={handleDelete}
288+
noData={
289+
<IllustratedMessage
290+
name={NoEntriesIllu}
291+
design={'Medium'}
292+
titleText={i18nBundle.getText(NO_VIEWS_DEFINED_TITLE)}
293+
subtitleText={i18nBundle.getText(NO_VIEWS_DEFINED_SUBTITLE)}
294+
/>
295+
}
271296
>
272297
{filteredProps.map((itemProps) => {
273298
return (

packages/main/src/components/VariantManagement/VariantManagement.cy.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,8 +666,9 @@ describe('VariantManagement', () => {
666666

667667
cy.get('[icon="navigation-down-arrow"]').click();
668668
cy.findByText('Manage').click();
669+
cy.get('[ui5-table-row-action][text="Delete View"]').as('deleteActions');
669670

670-
cy.get('[ui5-table-row-action][text="Delete View"]').each(($action) => {
671+
cy.get('@deleteActions').each(($action) => {
671672
if ($action.parent().attr('data-id') !== 'VariantItem 3') {
672673
cy.wrap($action).click();
673674
}
@@ -678,6 +679,21 @@ describe('VariantManagement', () => {
678679
cy.findByText(
679680
'{"nativeDetail":1,"deletedVariants":[{"children":"VariantItem 1"},{"selected":true,"children":"VariantItem 2"}],"prevVariants":[{"children":"VariantItem 1"},{"selected":true,"children":"VariantItem 2"},{"isDefault":true,"children":"VariantItem 3"}],"updatedVariants":[],"variants":[{"isDefault":true,"children":"VariantItem 3"}]}',
680681
);
682+
683+
cy.get('[icon="navigation-down-arrow"]').click();
684+
cy.findByText('Manage').click();
685+
686+
cy.get('@deleteActions').first().click();
687+
cy.focused().should('have.attr', 'ui5-table-row');
688+
cy.focused().should('have.attr', 'data-id', 'VariantItem 2');
689+
690+
cy.get('@deleteActions').last().click();
691+
cy.focused().should('have.attr', 'ui5-table-row');
692+
cy.focused().should('have.attr', 'data-id', 'VariantItem 2');
693+
694+
// no other rows remaining
695+
cy.get('@deleteActions').first().click();
696+
cy.findByText('Cancel').should('be.focused');
681697
});
682698

683699
it('Manage Views input validation', () => {

packages/main/src/i18n/messagebundle.properties

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#__ldi.translation.uuid=75c9c970-7315-49ab-bdac-9584ee66d3b8
22

3-
# https://openui5.hana.ondemand.com/topic/831039835e7c4da3a8a0b49567573afe
3+
# https://sdk.openui5.org/#/topic/831039835e7c4da3a8a0b49567573afe/
44

55
#XTXT
66
TARGET=Target
@@ -204,6 +204,12 @@ SELECT_VIEW=Select View
204204
#XACT: Label for the search variant input inside the VariantManagement Manage Views table
205205
SEARCH_VARIANT=Search variant
206206

207+
#XHED: Heading text for the IllustratedMessage component in the VariantManagement Manage Views dialog when no rows (views) are defined.
208+
NO_VIEWS_DEFINED_TITLE=No views available
209+
210+
#XMSG: Subheading text for the IllustratedMessage component in the Variant Management Manage Views dialog when no rows (views) are defined.
211+
NO_VIEWS_DEFINED_SUBTITLE=Please create some views.
212+
207213
#XBUT: Used in the MessageView component for filtering message types, should show messages of all types when selected
208214
ALL=All
209215

0 commit comments

Comments
 (0)