From 03ad035d3b865fbf4794838bedad26f2ef414cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Fri, 24 Nov 2023 13:59:31 +0100 Subject: [PATCH 1/2] Extract EnumerationFilter component --- .../src/components/dataviews/add-filter.js | 29 +++-------- .../dataviews/filter-enumeration.js | 52 +++++++++++++++++++ .../components/dataviews/filter-summary.js | 43 +++------------ 3 files changed, 65 insertions(+), 59 deletions(-) create mode 100644 packages/edit-site/src/components/dataviews/filter-enumeration.js diff --git a/packages/edit-site/src/components/dataviews/add-filter.js b/packages/edit-site/src/components/dataviews/add-filter.js index 7999ff413f96c..2ba32e0b5da77 100644 --- a/packages/edit-site/src/components/dataviews/add-filter.js +++ b/packages/edit-site/src/components/dataviews/add-filter.js @@ -14,12 +14,12 @@ import { __ } from '@wordpress/i18n'; */ import { unlock } from '../../lock-unlock'; import { ENUMERATION_TYPE, OPERATOR_IN } from './constants'; +import FilterEnumeration from './filter-enumeration'; const { DropdownMenuV2: DropdownMenu, DropdownSubMenuV2: DropdownSubMenu, DropdownSubMenuTriggerV2: DropdownSubMenuTrigger, - DropdownMenuItemV2: DropdownMenuItem, } = unlock( componentsPrivateApis ); export default function AddFilter( { fields, view, onChangeView } ) { @@ -78,28 +78,11 @@ export default function AddFilter( { fields, view, onChangeView } ) { } > - { filter.elements.map( ( element ) => ( - { - onChangeView( ( currentView ) => ( { - ...currentView, - page: 1, - filters: [ - ...currentView.filters, - { - field: filter.field, - operator: OPERATOR_IN, - value: element.value, - }, - ], - } ) ); - } } - role="menuitemcheckbox" - > - { element.label } - - ) ) } + ); } ) } diff --git a/packages/edit-site/src/components/dataviews/filter-enumeration.js b/packages/edit-site/src/components/dataviews/filter-enumeration.js new file mode 100644 index 0000000000000..c791b1ab81831 --- /dev/null +++ b/packages/edit-site/src/components/dataviews/filter-enumeration.js @@ -0,0 +1,52 @@ +/** + * WordPress dependencies + */ +import { privateApis as componentsPrivateApis } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; +import { OPERATOR_IN } from './constants'; + +const { DropdownMenuCheckboxItemV2: DropdownMenuCheckboxItem } = unlock( + componentsPrivateApis +); + +export default function ( { filter, view, onChangeView } ) { + const filterInView = view.filters.find( ( f ) => f.field === filter.field ); + const activeElement = filter.elements.find( + ( element ) => element.value === filterInView?.value + ); + + return filter.elements.map( ( element ) => { + return ( + + onChangeView( ( currentView ) => ( { + ...currentView, + page: 1, + filters: [ + ...view.filters.filter( + ( f ) => f.field !== filter.field + ), + { + field: filter.field, + operator: OPERATOR_IN, + value: + activeElement?.value === element.value + ? undefined + : element.value, + }, + ], + } ) ) + } + > + { element.label } + + ); + } ); +} diff --git a/packages/edit-site/src/components/dataviews/filter-summary.js b/packages/edit-site/src/components/dataviews/filter-summary.js index ae92d0cc46273..18ef0b0727a94 100644 --- a/packages/edit-site/src/components/dataviews/filter-summary.js +++ b/packages/edit-site/src/components/dataviews/filter-summary.js @@ -12,13 +12,10 @@ import { __, sprintf } from '@wordpress/i18n'; /** * Internal dependencies */ -import { OPERATOR_IN } from './constants'; import { unlock } from '../../lock-unlock'; +import FilterEnumeration from './filter-enumeration'; -const { - DropdownMenuV2: DropdownMenu, - DropdownMenuCheckboxItemV2: DropdownMenuCheckboxItem, -} = unlock( componentsPrivateApis ); +const { DropdownMenuV2: DropdownMenu } = unlock( componentsPrivateApis ); export default function FilterSummary( { filter, view, onChangeView } ) { const filterInView = view.filters.find( ( f ) => f.field === filter.field ); @@ -43,37 +40,11 @@ export default function FilterSummary( { filter, view, onChangeView } ) { } > - { filter.elements.map( ( element ) => { - return ( - - onChangeView( ( currentView ) => ( { - ...currentView, - page: 1, - filters: [ - ...view.filters.filter( - ( f ) => f.field !== filter.field - ), - { - field: filter.field, - operator: OPERATOR_IN, - value: - activeElement?.value === - element.value - ? undefined - : element.value, - }, - ], - } ) ) - } - > - { element.label } - - ); - } ) } + ); } From 67d5dec0eb24f8b30cda46a7ee631adf5e3eae96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Fri, 24 Nov 2023 17:38:02 +0100 Subject: [PATCH 2/2] Reuse FilterEnumeration in ViewList --- .../src/components/dataviews/view-list.js | 133 ++---------------- 1 file changed, 11 insertions(+), 122 deletions(-) diff --git a/packages/edit-site/src/components/dataviews/view-list.js b/packages/edit-site/src/components/dataviews/view-list.js index c5d0bd0d340fe..e87b4b3a53156 100644 --- a/packages/edit-site/src/components/dataviews/view-list.js +++ b/packages/edit-site/src/components/dataviews/view-list.js @@ -37,7 +37,9 @@ import { useMemo, Children, Fragment } from '@wordpress/element'; */ import { unlock } from '../../lock-unlock'; import ItemActions from './item-actions'; -import { ENUMERATION_TYPE, OPERATOR_IN } from './constants'; +import { ENUMERATION_TYPE } from './constants'; + +import FilterEnumeration from './filter-enumeration'; const { DropdownMenuV2: DropdownMenu, @@ -55,7 +57,7 @@ const sortingItemsInfo = { }; const sortIcons = { asc: chevronUp, desc: chevronDown }; -function HeaderMenu( { dataView, header } ) { +function HeaderMenu( { dataView, header, view, onChangeView } ) { if ( header.isPlaceholder ) { return null; } @@ -150,66 +152,11 @@ function HeaderMenu( { dataView, header } ) { } > - { filter.elements.map( ( element ) => { - let isActive = false; - const columnFilters = - dataView.getState().columnFilters; - const columnFilter = columnFilters.find( - ( f ) => - Object.keys( f )[ 0 ].split( - ':' - )[ 0 ] === filter.field - ); - - if ( columnFilter ) { - const value = - Object.values( columnFilter )[ 0 ]; - // Intentionally use loose comparison, so it does type conversion. - // This covers the case where a top-level filter for the same field converts a number into a string. - isActive = element.value == value; // eslint-disable-line eqeqeq - } - - return ( - - } - onSelect={ () => { - const otherFilters = - columnFilters?.filter( - ( f ) => { - const [ - field, - operator, - ] = - Object.keys( - f - )[ 0 ].split( ':' ); - return ( - field !== - filter.field || - operator !== - OPERATOR_IN - ); - } - ); - - dataView.setColumnFilters( [ - ...otherFilters, - { - [ filter.field + ':in' ]: - isActive - ? undefined - : element.value, - }, - ] ); - } } - > - { element.label } - - ); - } ) } + ) } @@ -281,58 +228,6 @@ function ViewList( { ); }, [ view.hiddenFields ] ); - /** - * Transform the filters from the view format into the tanstack columns filter format. - * - * Input: - * - * view.filters = [ - * { field: 'date', operator: 'before', value: '2020-01-01' }, - * { field: 'date', operator: 'after', value: '2020-01-01' }, - * ] - * - * Output: - * - * columnFilters = [ - * { "date:before": '2020-01-01' }, - * { "date:after": '2020-01-01' } - * ] - * - * @param {Array} filters The view filters to transform. - * @return {Array} The transformed TanStack column filters. - */ - const toTanStackColumnFilters = ( filters ) => - filters?.map( ( filter ) => ( { - [ filter.field + ':' + filter.operator ]: filter.value, - } ) ); - - /** - * Transform the filters from the view format into the tanstack columns filter format. - * - * Input: - * - * columnFilters = [ - * { "date:before": '2020-01-01'}, - * { "date:after": '2020-01-01' } - * ] - * - * Output: - * - * view.filters = [ - * { field: 'date', operator: 'before', value: '2020-01-01' }, - * { field: 'date', operator: 'after', value: '2020-01-01' }, - * ] - * - * @param {Array} filters The TanStack column filters to transform. - * @return {Array} The transformed view filters. - */ - const fromTanStackColumnFilters = ( filters ) => - filters.map( ( filter ) => { - const [ key, value ] = Object.entries( filter )[ 0 ]; - const [ field, operator ] = key.split( ':' ); - return { field, operator, value }; - } ); - const shownData = useAsyncList( data ); const dataView = useReactTable( { data: shownData, @@ -351,7 +246,6 @@ function ViewList( { ] : [], globalFilter: view.search, - columnFilters: toTanStackColumnFilters( view.filters ), pagination: { pageIndex: view.page, pageSize: view.perPage, @@ -413,13 +307,6 @@ function ViewList( { onGlobalFilterChange: ( value ) => { onChangeView( { ...view, search: value, page: 1 } ); }, - onColumnFiltersChange: ( columnFiltersUpdater ) => { - onChangeView( { - ...view, - filters: fromTanStackColumnFilters( columnFiltersUpdater() ), - page: 1, - } ); - }, onPaginationChange: ( paginationUpdater ) => { onChangeView( ( currentView ) => { const { pageIndex, pageSize } = paginationUpdater( { @@ -469,6 +356,8 @@ function ViewList( { ) ) }