From 10472ea0e1bc925647f5fc1bfaafd59ca3ea6c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Thu, 23 Nov 2023 13:26:05 +0100 Subject: [PATCH 01/16] Add support for not in filter --- packages/dataviews/src/constants.js | 1 + packages/dataviews/src/filter-summary.js | 113 ++++++++++++++++-- packages/dataviews/src/filters.js | 7 +- .../src/components/page-pages/index.js | 14 +++ 4 files changed, 122 insertions(+), 13 deletions(-) diff --git a/packages/dataviews/src/constants.js b/packages/dataviews/src/constants.js index 8394b52bf172f0..c4d1d9242f08a3 100644 --- a/packages/dataviews/src/constants.js +++ b/packages/dataviews/src/constants.js @@ -16,6 +16,7 @@ export const ENUMERATION_TYPE = 'enumeration'; // Filter operators. export const OPERATOR_IN = 'in'; +export const OPERATOR_NOT_IN = 'notIn'; // View layouts. export const LAYOUT_TABLE = 'table'; diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index 64a5b39bf74a6d..35b4ce0cc70c5f 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -12,15 +12,54 @@ import { __, sprintf } from '@wordpress/i18n'; /** * Internal dependencies */ -import { OPERATOR_IN } from './constants'; -import { unlock } from './lock-unlock'; +import { OPERATOR_IN, OPERATOR_NOT_IN } from './constants'; +import { unlock } from '../../lock-unlock'; const { DropdownMenuV2: DropdownMenu, DropdownMenuCheckboxItemV2: DropdownMenuCheckboxItem, + DropdownMenuSeparatorV2: DropdownMenuSeparator, + DropdownSubMenuV2: DropdownSubMenu, + DropdownSubMenuTriggerV2: DropdownSubMenuTrigger, } = unlock( componentsPrivateApis ); -export default function FilterSummary( { filter, view, onChangeView } ) { +const FilterText = ( { activeElement, filterInView, filter } ) => { + if ( activeElement === undefined ) { + return filter.name; + } + + if ( + activeElement !== undefined && + filterInView?.operator === OPERATOR_IN + ) { + return sprintf( + /* translators: 1: Filter name. 2: Filter value. e.g.: "Author is Admin". */ + __( '%1$s is %2$s' ), + filter.name, + activeElement.label + ); + } + + if ( + activeElement !== undefined && + filterInView?.operator === OPERATOR_NOT_IN + ) { + return sprintf( + /* translators: 1: Filter name. 2: Filter value. e.g.: "Author is not Admin". */ + __( '%1$s is not %2$s' ), + filter.name, + activeElement.label + ); + } + + return sprintf( + /* translators: 1: Filter name e.g.: "Unknown status for Author". */ + __( 'Unknown status for %1$s' ), + filter.name + ); +}; + +export function FilterSummary( { filter, view, onChangeView } ) { const filterInView = view.filters.find( ( f ) => f.field === filter.field ); const activeElement = filter.elements.find( ( element ) => element.value === filterInView?.value @@ -31,14 +70,11 @@ export default function FilterSummary( { filter, view, onChangeView } ) { key={ filter.field } trigger={ } @@ -74,6 +110,61 @@ export default function FilterSummary( { filter, view, onChangeView } ) { ); } ) } + + + { __( 'Settings' ) } + + } + > + + onChangeView( ( currentView ) => ( { + ...currentView, + page: 1, + filters: [ + ...view.filters.filter( + ( f ) => f.field !== filter.field + ), + { + field: filter.field, + operator: OPERATOR_IN, + value: filterInView?.value, + }, + ], + } ) ) + } + > + { __( 'Show matches' ) } + + + onChangeView( ( currentView ) => ( { + ...currentView, + page: 1, + filters: [ + ...view.filters.filter( + ( f ) => f.field !== filter.field + ), + { + field: filter.field, + operator: OPERATOR_NOT_IN, + value: filterInView?.value, + }, + ], + } ) ) + } + > + { __( 'Hide matches' ) } + + ); } diff --git a/packages/dataviews/src/filters.js b/packages/dataviews/src/filters.js index 0583fd1e45eb60..acdb44e461d9e6 100644 --- a/packages/dataviews/src/filters.js +++ b/packages/dataviews/src/filters.js @@ -4,7 +4,7 @@ import FilterSummary from './filter-summary'; import AddFilter from './add-filter'; import ResetFilters from './reset-filters'; -import { ENUMERATION_TYPE, OPERATOR_IN } from './constants'; +import { ENUMERATION_TYPE, OPERATOR_IN, OPERATOR_NOT_IN } from './constants'; export default function Filters( { fields, view, onChangeView } ) { const filters = []; @@ -21,7 +21,10 @@ export default function Filters( { fields, view, onChangeView } ) { elements: field.elements || [], isVisible: view.filters.some( ( f ) => - f.field === field.id && f.operator === OPERATOR_IN + f.field === field.id && + [ OPERATOR_IN, OPERATOR_NOT_IN ].includes( + f.operator + ) ), } ); } diff --git a/packages/edit-site/src/components/page-pages/index.js b/packages/edit-site/src/components/page-pages/index.js index 5819b825865ef5..1855a347b17269 100644 --- a/packages/edit-site/src/components/page-pages/index.js +++ b/packages/edit-site/src/components/page-pages/index.js @@ -26,6 +26,15 @@ import { */ import Page from '../page'; import Link from '../routes/link'; +import { + DataViews, + VIEW_LAYOUTS, + ENUMERATION_TYPE, + LAYOUT_GRID, + LAYOUT_TABLE, + OPERATOR_IN, + OPERATOR_NOT_IN, +} from '../dataviews'; import { default as DEFAULT_VIEWS } from '../sidebar-dataviews/default-views'; import { trashPostAction, @@ -139,6 +148,11 @@ export default function PagePages() { filter.operator === OPERATOR_IN ) { filters.author = filter.value; + } else if ( + filter.field === 'author' && + filter.operator === OPERATOR_NOT_IN + ) { + filters.author_exclude = filter.value; } } ); // We want to provide a different default item for the status filter From f3fb592eaf7ee519b00d2499e6d6923be36b6807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Thu, 23 Nov 2023 14:13:30 +0100 Subject: [PATCH 02/16] Field API: allow declaring which operators a field supports --- packages/dataviews/README.md | 2 + packages/dataviews/src/filter-summary.js | 191 ++++++++++-------- packages/dataviews/src/filters.js | 4 + .../src/components/page-pages/index.js | 3 + 4 files changed, 116 insertions(+), 84 deletions(-) diff --git a/packages/dataviews/README.md b/packages/dataviews/README.md index 52fff8269d2459..99b36d8f53c11c 100644 --- a/packages/dataviews/README.md +++ b/packages/dataviews/README.md @@ -185,6 +185,8 @@ Example: - `type`: the type of the field. Used to generate the proper filters. Only `enumeration` available at the moment. - `enableSorting`: whether the data can be sorted by the given field. True by default. - `enableHiding`: whether the field can be hidden. True by default. +- `filterBy`: configuration for the filters. + - `operators`: the list of operators supported by the field. ## Actions diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index 35b4ce0cc70c5f..a32162ea9bc0a1 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -8,6 +8,7 @@ import { } from '@wordpress/components'; import { chevronDown } from '@wordpress/icons'; import { __, sprintf } from '@wordpress/i18n'; +import { Children, Fragment } from '@wordpress/element'; /** * Internal dependencies @@ -17,6 +18,7 @@ import { unlock } from '../../lock-unlock'; const { DropdownMenuV2: DropdownMenu, + DropdownMenuGroupV2: DropdownMenuGroup, DropdownMenuCheckboxItemV2: DropdownMenuCheckboxItem, DropdownMenuSeparatorV2: DropdownMenuSeparator, DropdownSubMenuV2: DropdownSubMenu, @@ -59,6 +61,17 @@ const FilterText = ( { activeElement, filterInView, filter } ) => { ); }; +function WithSeparators( { children } ) { + return Children.toArray( children ) + .filter( Boolean ) + .map( ( child, i ) => ( + + { i > 0 && } + { child } + + ) ); +} + export function FilterSummary( { filter, view, onChangeView } ) { const filterInView = view.filters.find( ( f ) => f.field === filter.field ); const activeElement = filter.elements.find( @@ -79,92 +92,102 @@ export 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, - }, - ], - } ) ) + + + { 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 } + + ); + } ) } + + { filter.operators.length > 1 && ( + + { __( 'Settings' ) } + } > - { element.label } - - ); - } ) } - - - { __( 'Settings' ) } - - } - > - - onChangeView( ( currentView ) => ( { - ...currentView, - page: 1, - filters: [ - ...view.filters.filter( - ( f ) => f.field !== filter.field - ), - { - field: filter.field, - operator: OPERATOR_IN, - value: filterInView?.value, - }, - ], - } ) ) - } - > - { __( 'Show matches' ) } - - - onChangeView( ( currentView ) => ( { - ...currentView, - page: 1, - filters: [ - ...view.filters.filter( - ( f ) => f.field !== filter.field - ), - { - field: filter.field, - operator: OPERATOR_NOT_IN, - value: filterInView?.value, - }, - ], - } ) ) - } - > - { __( 'Hide matches' ) } - - + + onChangeView( ( currentView ) => ( { + ...currentView, + page: 1, + filters: [ + ...view.filters.filter( + ( f ) => f.field !== filter.field + ), + { + field: filter.field, + operator: OPERATOR_IN, + value: filterInView?.value, + }, + ], + } ) ) + } + > + { __( 'Show matches' ) } + + + onChangeView( ( currentView ) => ( { + ...currentView, + page: 1, + filters: [ + ...view.filters.filter( + ( f ) => f.field !== filter.field + ), + { + field: filter.field, + operator: OPERATOR_NOT_IN, + value: filterInView?.value, + }, + ], + } ) ) + } + > + { __( 'Hide matches' ) } + + + ) } + ); } diff --git a/packages/dataviews/src/filters.js b/packages/dataviews/src/filters.js index acdb44e461d9e6..f594ee271e108d 100644 --- a/packages/dataviews/src/filters.js +++ b/packages/dataviews/src/filters.js @@ -19,6 +19,10 @@ export default function Filters( { fields, view, onChangeView } ) { field: field.id, name: field.header, elements: field.elements || [], + operators: field.filterBy?.operators || [ + OPERATOR_IN, + OPERATOR_NOT_IN, + ], isVisible: view.filters.some( ( f ) => f.field === field.id && diff --git a/packages/edit-site/src/components/page-pages/index.js b/packages/edit-site/src/components/page-pages/index.js index 1855a347b17269..1ebe4f9185e6ef 100644 --- a/packages/edit-site/src/components/page-pages/index.js +++ b/packages/edit-site/src/components/page-pages/index.js @@ -265,6 +265,9 @@ export default function PagePages() { type: ENUMERATION_TYPE, elements: STATUSES, enableSorting: false, + filterBy: { + operators: [ OPERATOR_IN ], + }, }, { header: __( 'Date' ), From d4f9d092c3b41f45d9403ce608f25dbf7a21c096 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Mon, 27 Nov 2023 17:36:06 +0100 Subject: [PATCH 03/16] Fix rebase --- packages/dataviews/src/filter-summary.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index a32162ea9bc0a1..bf1c25e4096ff9 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -72,7 +72,7 @@ function WithSeparators( { children } ) { ) ); } -export function FilterSummary( { filter, view, onChangeView } ) { +export default function FilterSummary( { filter, view, onChangeView } ) { const filterInView = view.filters.find( ( f ) => f.field === filter.field ); const activeElement = filter.elements.find( ( element ) => element.value === filterInView?.value From ac468f17d8b9673aac2465e55ef40f58bf4a789f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Mon, 27 Nov 2023 17:40:05 +0100 Subject: [PATCH 04/16] Fix: do not change operator --- packages/dataviews/src/filter-summary.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index bf1c25e4096ff9..694649590b442e 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -113,7 +113,9 @@ export default function FilterSummary( { filter, view, onChangeView } ) { ), { field: filter.field, - operator: OPERATOR_IN, + operator: + filterInView?.operator || + filter.operators[ 0 ], value: activeElement?.value === element.value From 40c25c36ba9b8a5b57843be9d18ba9ea7ca3e1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Tue, 28 Nov 2023 18:11:33 +0100 Subject: [PATCH 05/16] Do not register filter if it does not support any operator --- packages/dataviews/src/filters.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/dataviews/src/filters.js b/packages/dataviews/src/filters.js index f594ee271e108d..e2d24e7a848eea 100644 --- a/packages/dataviews/src/filters.js +++ b/packages/dataviews/src/filters.js @@ -6,6 +6,16 @@ import AddFilter from './add-filter'; import ResetFilters from './reset-filters'; import { ENUMERATION_TYPE, OPERATOR_IN, OPERATOR_NOT_IN } from './constants'; +const operatorsFromField = ( field ) => { + let operators = field.filterBy?.operators; + if ( ! operators || ! Array.isArray( operators ) ) { + operators = [ OPERATOR_IN, OPERATOR_NOT_IN ]; + } + return operators.filter( ( operator ) => + [ OPERATOR_IN, OPERATOR_NOT_IN ].includes( operator ) + ); +}; + export default function Filters( { fields, view, onChangeView } ) { const filters = []; fields.forEach( ( field ) => { @@ -13,16 +23,18 @@ export default function Filters( { fields, view, onChangeView } ) { return; } + const operators = operatorsFromField( field ); + if ( operators.length === 0 ) { + return; + } + switch ( field.type ) { case ENUMERATION_TYPE: filters.push( { field: field.id, name: field.header, elements: field.elements || [], - operators: field.filterBy?.operators || [ - OPERATOR_IN, - OPERATOR_NOT_IN, - ], + operators, isVisible: view.filters.some( ( f ) => f.field === field.id && From fe31c567a3075830c503b98b54f9f4bf7ebedf93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Thu, 30 Nov 2023 11:44:10 +0100 Subject: [PATCH 06/16] FilterSummary: improve semantics --- packages/dataviews/src/filter-summary.js | 40 ++++++++++++++---------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index 694649590b442e..1c27c6a827e0c2 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -6,7 +6,7 @@ import { privateApis as componentsPrivateApis, Icon, } from '@wordpress/components'; -import { chevronDown } from '@wordpress/icons'; +import { chevronDown, check } from '@wordpress/icons'; import { __, sprintf } from '@wordpress/i18n'; import { Children, Fragment } from '@wordpress/element'; @@ -19,7 +19,7 @@ import { unlock } from '../../lock-unlock'; const { DropdownMenuV2: DropdownMenu, DropdownMenuGroupV2: DropdownMenuGroup, - DropdownMenuCheckboxItemV2: DropdownMenuCheckboxItem, + DropdownMenuItemV2: DropdownMenuItem, DropdownMenuSeparatorV2: DropdownMenuSeparator, DropdownSubMenuV2: DropdownSubMenu, DropdownSubMenuTriggerV2: DropdownSubMenuTrigger, @@ -96,11 +96,13 @@ export default function FilterSummary( { filter, view, onChangeView } ) { { filter.elements.map( ( element ) => { return ( - + ) } onSelect={ () => onChangeView( ( currentView ) => ( { @@ -127,7 +129,7 @@ export default function FilterSummary( { filter, view, onChangeView } ) { } > { element.label } - + ); } ) } @@ -139,10 +141,14 @@ export default function FilterSummary( { filter, view, onChangeView } ) { } > - + ) + } onSelect={ () => onChangeView( ( currentView ) => ( { ...currentView, @@ -161,12 +167,14 @@ export default function FilterSummary( { filter, view, onChangeView } ) { } > { __( 'Show matches' ) } - - + + ) } onSelect={ () => onChangeView( ( currentView ) => ( { @@ -186,7 +194,7 @@ export default function FilterSummary( { filter, view, onChangeView } ) { } > { __( 'Hide matches' ) } - + ) } From c4431398ea145b1530b0a85146c91779ff772990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:12:17 +0100 Subject: [PATCH 07/16] Add aria-checked --- packages/dataviews/src/filter-summary.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index 1c27c6a827e0c2..0b27e3e5f626a6 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -99,6 +99,9 @@ export default function FilterSummary( { filter, view, onChangeView } ) { @@ -144,6 +147,9 @@ export default function FilterSummary( { filter, view, onChangeView } ) { @@ -171,6 +177,9 @@ export default function FilterSummary( { filter, view, onChangeView } ) { From c2a794930b3366601ecd179e82cc8cd9a8453913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:14:46 +0100 Subject: [PATCH 08/16] Use Conditions instead of Settings --- packages/dataviews/src/filter-summary.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index 0b27e3e5f626a6..cdeaa29c26e0a7 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -140,7 +140,7 @@ export default function FilterSummary( { filter, view, onChangeView } ) { - { __( 'Settings' ) } + { __( 'Conditions' ) } } > From 91ebe822bea35a25a55f9b47650157293a1d5c66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:15:36 +0100 Subject: [PATCH 09/16] Use Is/Is not --- packages/dataviews/src/filter-summary.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index cdeaa29c26e0a7..55434c13904efc 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -172,7 +172,7 @@ export default function FilterSummary( { filter, view, onChangeView } ) { } ) ) } > - { __( 'Show matches' ) } + { __( 'Is' ) } - { __( 'Hide matches' ) } + { __( 'Is not' ) } ) } From bf74922c9e9b270cce683836ca9c49c014a4e60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:37:28 +0100 Subject: [PATCH 10/16] Show condition is submenu trigger --- packages/dataviews/src/filter-summary.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index 55434c13904efc..c7d0f2c9cbda19 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -6,7 +6,7 @@ import { privateApis as componentsPrivateApis, Icon, } from '@wordpress/components'; -import { chevronDown, check } from '@wordpress/icons'; +import { chevronDown, chevronRightSmall, check } from '@wordpress/icons'; import { __, sprintf } from '@wordpress/i18n'; import { Children, Fragment } from '@wordpress/element'; @@ -139,7 +139,16 @@ export default function FilterSummary( { filter, view, onChangeView } ) { { filter.operators.length > 1 && ( + + { filterInView.operator === OPERATOR_IN + ? __( 'Is' ) + : __( 'Is not' ) } + { ' ' } + + } + > { __( 'Conditions' ) } } From 162d71fd51d487dbde6ba308896d3c13dadd13a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:45:57 +0100 Subject: [PATCH 11/16] Use right or left depending on RTL --- packages/dataviews/src/filter-summary.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index c7d0f2c9cbda19..be01331e5c1127 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -6,8 +6,13 @@ import { privateApis as componentsPrivateApis, Icon, } from '@wordpress/components'; -import { chevronDown, chevronRightSmall, check } from '@wordpress/icons'; -import { __, sprintf } from '@wordpress/i18n'; +import { + chevronDown, + chevronRightSmall, + check, + chevronLeftSmall, +} from '@wordpress/icons'; +import { __, sprintf, isRTL } from '@wordpress/i18n'; import { Children, Fragment } from '@wordpress/element'; /** @@ -145,7 +150,13 @@ export default function FilterSummary( { filter, view, onChangeView } ) { { filterInView.operator === OPERATOR_IN ? __( 'Is' ) : __( 'Is not' ) } - { ' ' } + { ' ' } } > From 5c1e48c94ae942ca02b6fe5bd8a9c884868d1500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:15:02 +0100 Subject: [PATCH 12/16] Fix rebase --- packages/dataviews/src/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/dataviews/src/index.js b/packages/dataviews/src/index.js index 7f429923ef4b13..01fdaeae0073bf 100644 --- a/packages/dataviews/src/index.js +++ b/packages/dataviews/src/index.js @@ -6,4 +6,5 @@ export { LAYOUT_LIST, ENUMERATION_TYPE, OPERATOR_IN, + OPERATOR_NOT_IN, } from './constants'; From 9497e67e49af4f6b683fc1ca6bb6137db9054f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:16:10 +0100 Subject: [PATCH 13/16] Revert "Use right or left depending on RTL" This reverts commit 24e5ef3c261c3c10f14735b7fde747b3ee382e87. --- packages/dataviews/src/filter-summary.js | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index be01331e5c1127..c7d0f2c9cbda19 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -6,13 +6,8 @@ import { privateApis as componentsPrivateApis, Icon, } from '@wordpress/components'; -import { - chevronDown, - chevronRightSmall, - check, - chevronLeftSmall, -} from '@wordpress/icons'; -import { __, sprintf, isRTL } from '@wordpress/i18n'; +import { chevronDown, chevronRightSmall, check } from '@wordpress/icons'; +import { __, sprintf } from '@wordpress/i18n'; import { Children, Fragment } from '@wordpress/element'; /** @@ -150,13 +145,7 @@ export default function FilterSummary( { filter, view, onChangeView } ) { { filterInView.operator === OPERATOR_IN ? __( 'Is' ) : __( 'Is not' ) } - { ' ' } + { ' ' } } > From 38199066ac8f92649b7b06f7b30fb3aa1d011302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:18:28 +0100 Subject: [PATCH 14/16] Fix rebase --- packages/dataviews/src/view-table.js | 224 +++++++++++++++++++-------- 1 file changed, 159 insertions(+), 65 deletions(-) diff --git a/packages/dataviews/src/view-table.js b/packages/dataviews/src/view-table.js index bf2817293172c4..8b6422b4be11a7 100644 --- a/packages/dataviews/src/view-table.js +++ b/packages/dataviews/src/view-table.js @@ -37,7 +37,7 @@ 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, OPERATOR_IN, OPERATOR_NOT_IN } from './constants'; const { DropdownMenuV2: DropdownMenu, @@ -70,15 +70,49 @@ function HeaderMenu( { dataView, header } ) { } const sortedDirection = header.column.getIsSorted(); - let filter; + let filter, filterInView; + const otherFilters = []; if ( header.column.columnDef.type === ENUMERATION_TYPE ) { - filter = { - field: header.column.columnDef.id, - elements: header.column.columnDef.elements || [], - }; + let columnOperators = header.column.columnDef.filterBy?.operators; + if ( ! columnOperators || ! Array.isArray( columnOperators ) ) { + columnOperators = [ OPERATOR_IN, OPERATOR_NOT_IN ]; + } + const operators = columnOperators.filter( ( operator ) => + [ OPERATOR_IN, OPERATOR_NOT_IN ].includes( operator ) + ); + if ( operators.length >= 0 ) { + filter = { + field: header.column.columnDef.id, + operators, + elements: header.column.columnDef.elements || [], + }; + filterInView = { + field: filter.field, + operator: filter.operators[ 0 ], + value: undefined, + }; + } } const isFilterable = !! filter; + if ( isFilterable ) { + const columnFilters = dataView.getState().columnFilters; + columnFilters.forEach( ( columnFilter ) => { + const [ field, operator ] = + Object.keys( columnFilter )[ 0 ].split( ':' ); + const value = Object.values( columnFilter )[ 0 ]; + if ( field === filter.field ) { + filterInView = { + field, + operator, + value, + }; + } else { + otherFilters.push( columnFilter ); + } + } ); + } + return ( } > - { 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 ( - + + + { filter.elements.map( ( element ) => { + let isActive = false; + if ( filterInView ) { + // 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. + /* eslint-disable eqeqeq */ + isActive = + element.value == + filterInView.value; + /* eslint-enable eqeqeq */ } - 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, - }, - ] ); - } } + return ( + + ) + } + onSelect={ () => { + dataView.setColumnFilters( [ + ...otherFilters, + { + [ filter.field + + ':' + + filterInView?.operator ]: + isActive + ? undefined + : element.value, + }, + ] ); + } } + > + { element.label } + + ); + } ) } + + { filter.operators.length > 1 && ( + + { filterInView.operator === + OPERATOR_IN + ? __( 'Is' ) + : __( 'Is not' ) } + { ' ' } + + } + > + { __( 'Conditions' ) } + + } > - { element.label } - - ); - } ) } + + ) + } + onSelect={ () => + dataView.setColumnFilters( [ + ...otherFilters, + { + [ filter.field + + ':' + + OPERATOR_IN ]: + filterInView?.value, + }, + ] ) + } + > + { __( 'Is' ) } + + + ) + } + onSelect={ () => + dataView.setColumnFilters( [ + ...otherFilters, + { + [ filter.field + + ':' + + OPERATOR_NOT_IN ]: + filterInView?.value, + }, + ] ) + } + > + { __( 'Is not' ) } + + + ) } + ) } From 0c14102938d40fa084bcfdadfb4cdc90cb22106e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:20:13 +0100 Subject: [PATCH 15/16] Fix AddFilter: ignore operator to decide which filters to list --- packages/dataviews/src/add-filter.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/dataviews/src/add-filter.js b/packages/dataviews/src/add-filter.js index 91b35e04aab967..715135a533fb4b 100644 --- a/packages/dataviews/src/add-filter.js +++ b/packages/dataviews/src/add-filter.js @@ -36,8 +36,7 @@ export default function AddFilter( { fields, view, onChangeView } ) { name: field.header, elements: field.elements || [], isVisible: view.filters.some( - ( f ) => - f.field === field.id && f.operator === OPERATOR_IN + ( f ) => f.field === field.id ), } ); } From c493dbf9fa15eab44138a5d6592313ab73bd8dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Maneiro?= <583546+oandregal@users.noreply.github.com> Date: Mon, 4 Dec 2023 09:15:36 +0100 Subject: [PATCH 16/16] Fix rebase --- packages/dataviews/src/filter-summary.js | 2 +- .../edit-site/src/components/page-pages/index.js | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js index c7d0f2c9cbda19..3c30c6837103a7 100644 --- a/packages/dataviews/src/filter-summary.js +++ b/packages/dataviews/src/filter-summary.js @@ -14,7 +14,7 @@ import { Children, Fragment } from '@wordpress/element'; * Internal dependencies */ import { OPERATOR_IN, OPERATOR_NOT_IN } from './constants'; -import { unlock } from '../../lock-unlock'; +import { unlock } from './lock-unlock'; const { DropdownMenuV2: DropdownMenu, diff --git a/packages/edit-site/src/components/page-pages/index.js b/packages/edit-site/src/components/page-pages/index.js index 1ebe4f9185e6ef..cc56aa15122f2c 100644 --- a/packages/edit-site/src/components/page-pages/index.js +++ b/packages/edit-site/src/components/page-pages/index.js @@ -15,10 +15,11 @@ import { useSelect, useDispatch } from '@wordpress/data'; import { DataViews, ENUMERATION_TYPE, - VIEW_LAYOUTS, - OPERATOR_IN, LAYOUT_GRID, LAYOUT_TABLE, + OPERATOR_IN, + OPERATOR_NOT_IN, + VIEW_LAYOUTS, } from '@wordpress/dataviews'; /** @@ -26,15 +27,6 @@ import { */ import Page from '../page'; import Link from '../routes/link'; -import { - DataViews, - VIEW_LAYOUTS, - ENUMERATION_TYPE, - LAYOUT_GRID, - LAYOUT_TABLE, - OPERATOR_IN, - OPERATOR_NOT_IN, -} from '../dataviews'; import { default as DEFAULT_VIEWS } from '../sidebar-dataviews/default-views'; import { trashPostAction,