From 8361389eb971460a9512c242ed977ac0078db309 Mon Sep 17 00:00:00 2001 From: Yan Wang Date: Wed, 27 Sep 2023 17:11:00 +0800 Subject: [PATCH] feat(faceted-search/BadgeMenu): "Show selected" toggle on BadgeMenu (#4908) * add 'show selected' toggle for BadgeMenu * changeset --- .changeset/smooth-dodos-dance.md | 5 +++ .../Badges/BadgeMenu/BadgeMenu.module.scss | 5 +++ .../BadgeMenu/BadgeMenuForm.component.js | 40 +++++++++++++++---- .../BadgeMenu/BadgeMenuForm.component.test.js | 32 +++++++++++++++ 4 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 .changeset/smooth-dodos-dance.md diff --git a/.changeset/smooth-dodos-dance.md b/.changeset/smooth-dodos-dance.md new file mode 100644 index 00000000000..655e6d3bd9c --- /dev/null +++ b/.changeset/smooth-dodos-dance.md @@ -0,0 +1,5 @@ +--- +'@talend/react-faceted-search': minor +--- + +"Show selected" toggle on BadgeMenu diff --git a/packages/faceted-search/src/components/Badges/BadgeMenu/BadgeMenu.module.scss b/packages/faceted-search/src/components/Badges/BadgeMenu/BadgeMenu.module.scss index ba53cfe9cd0..8b1cb63fbd8 100644 --- a/packages/faceted-search/src/components/Badges/BadgeMenu/BadgeMenu.module.scss +++ b/packages/faceted-search/src/components/Badges/BadgeMenu/BadgeMenu.module.scss @@ -21,6 +21,10 @@ $popover-screen-width: tokens.$coral-sizing-maximal; .menu-items-filter { margin: 0; + + :global(.btn) { + margin: 0; + } } } @@ -42,5 +46,6 @@ $popover-screen-width: tokens.$coral-sizing-maximal; :global(.tc-tooltip-footer) { min-width: auto; width: $popover-screen-width; + padding-left: 0; } } diff --git a/packages/faceted-search/src/components/Badges/BadgeMenu/BadgeMenuForm.component.js b/packages/faceted-search/src/components/Badges/BadgeMenu/BadgeMenuForm.component.js index 7b8a49ed1af..31469c66253 100644 --- a/packages/faceted-search/src/components/Badges/BadgeMenu/BadgeMenuForm.component.js +++ b/packages/faceted-search/src/components/Badges/BadgeMenu/BadgeMenuForm.component.js @@ -1,6 +1,7 @@ /* eslint-disable jsx-a11y/no-autofocus */ -import { useCallback, useState } from 'react'; +import { useMemo, useState } from 'react'; import get from 'lodash/get'; +import isEmpty from 'lodash/isEmpty'; import PropTypes from 'prop-types'; import { DropdownButton } from '@talend/design-system'; import { Action } from '@talend/react-components/lib/Actions'; @@ -21,12 +22,15 @@ const createRowItemEntity = value => option => { }; }; -const getRows = (values, value, filterValue) => { - const formatFilterValue = filterValue.trim().toLocaleLowerCase(); +const getRows = (values, value) => { + return values.map(createRowItemEntity(value)); +}; - return values +const getVisibleRows = (rows, filterValue, showAll) => { + const formatFilterValue = filterValue.trim().toLocaleLowerCase(); + return rows .filter(option => get(option, 'label', '').toLocaleLowerCase().includes(formatFilterValue)) - .map(createRowItemEntity(value)); + .filter(row => (showAll ? true : row.checked)); }; const BadgeMenuForm = ({ @@ -40,9 +44,17 @@ const BadgeMenuForm = ({ ...rest }) => { const [filter, setFilter] = useState(''); + const [showAll, setShowAll] = useState(true); const badgeMenuFormId = `${id}-menu-form`; - const items = useCallback(getRows(values, value, filter), [values, value, filter]); + const items = useMemo(() => getRows(values, value), [values, value]); + const visibleItems = useMemo( + () => getVisibleRows(items, filter, showAll), + [items, filter, showAll], + ); + const showSelectedToggleLabel = showAll + ? t('SHOW_SELECTED_ITEM', { defaultValue: 'Selected' }) + : t('SHOW_ALL_ITMES', { defaultValue: 'Show all' }); return ( <> @@ -72,7 +84,7 @@ const BadgeMenuForm = ({ onSubmit={onSubmit} > - {items.map(rowItem => { + {visibleItems.map(rowItem => { return ( +
+ {!isEmpty(value) && ( + { + setShowAll(!showAll); + setFilter(''); + }} + label={showSelectedToggleLabel} + bsStyle="link" + className={theme('fs-badge-menu-form-left-button')} + /> + )} +
{ expect(screen.queryByTestId('badge-menu-form-item-item-two')).not.toBeInTheDocument(); expect(screen.queryByTestId('badge-menu-form-item-item-three')).not.toBeInTheDocument(); }); + it('should show selected item when click on "Selected" button', () => { + // Given + const props = { + id: 'myId', + value: { + id: 'item-one', + label: 'Item One', + }, + values: menuItems, + onChange: jest.fn(), + onSubmit: jest.fn(), + t, + }; + // When + render(); + // Then all items are visible by default + expect(screen.getByTestId('badge-menu-form-item-item-one')).toBeVisible(); + expect(screen.getByTestId('badge-menu-form-item-item-two')).toBeVisible(); + expect(screen.getByTestId('badge-menu-form-item-item-three')).toBeVisible(); + // When click on "Selected" button + userEvent.click(screen.getByRole('button', { name: /selected/i })); + // Then only item One is visible + expect(screen.getByTestId('badge-menu-form-item-item-one')).toBeVisible(); + expect(screen.queryByTestId('badge-menu-form-item-item-two')).not.toBeInTheDocument(); + expect(screen.queryByTestId('badge-menu-form-item-item-three')).not.toBeInTheDocument(); + // When click on "Show all" button + userEvent.click(screen.getByRole('button', { name: /show all/i })); + // Then all items are visible + expect(screen.getByTestId('badge-menu-form-item-item-one')).toBeVisible(); + expect(screen.getByTestId('badge-menu-form-item-item-two')).toBeVisible(); + expect(screen.getByTestId('badge-menu-form-item-item-three')).toBeVisible(); + }); it('should call the submit callback', () => { const onSubmit = jest.fn();