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,