diff --git a/packages/dataviews/src/add-filter.js b/packages/dataviews/src/add-filter.js
index 715135a533fb4..5403d36703128 100644
--- a/packages/dataviews/src/add-filter.js
+++ b/packages/dataviews/src/add-filter.js
@@ -6,101 +6,299 @@ import {
Button,
Icon,
} from '@wordpress/components';
-import { chevronRightSmall, plus } from '@wordpress/icons';
-import { __ } from '@wordpress/i18n';
+import { chevronRightSmall, funnel, check } from '@wordpress/icons';
+import { __, sprintf } from '@wordpress/i18n';
+import { Children, Fragment } from '@wordpress/element';
/**
* Internal dependencies
*/
import { unlock } from './lock-unlock';
-import { ENUMERATION_TYPE, OPERATOR_IN } from './constants';
+import { LAYOUT_LIST, OPERATOR_IN, OPERATOR_NOT_IN } from './constants';
const {
DropdownMenuV2: DropdownMenu,
+ DropdownMenuGroupV2: DropdownMenuGroup,
DropdownSubMenuV2: DropdownSubMenu,
DropdownSubMenuTriggerV2: DropdownSubMenuTrigger,
DropdownMenuItemV2: DropdownMenuItem,
+ DropdownMenuSeparatorV2: DropdownMenuSeparator,
} = unlock( componentsPrivateApis );
-export default function AddFilter( { fields, view, onChangeView } ) {
- const filters = [];
- fields.forEach( ( field ) => {
- if ( ! field.type ) {
- return;
- }
-
- switch ( field.type ) {
- case ENUMERATION_TYPE:
- filters.push( {
- field: field.id,
- name: field.header,
- elements: field.elements || [],
- isVisible: view.filters.some(
- ( f ) => f.field === field.id
- ),
- } );
- }
- } );
+function WithSeparators( { children } ) {
+ return Children.toArray( children )
+ .filter( Boolean )
+ .map( ( child, i ) => (
+
+ { i > 0 && }
+ { child }
+
+ ) );
+}
+export default function AddFilter( { filters, view, onChangeView } ) {
if ( filters.length === 0 ) {
return null;
}
+ const filterCount = view.filters.reduce( ( acc, filter ) => {
+ if ( filter.value !== undefined ) {
+ return acc + 1;
+ }
+ return acc;
+ }, 0 );
+
return (
-
- { __( 'Add filter' ) }
+ { view.type === LAYOUT_LIST && filterCount > 0 ? (
+
+ { filterCount }
+
+ ) : null }
}
>
- { filters.map( ( filter ) => {
- if ( filter.isVisible ) {
- return null;
- }
-
- return (
- }
+
+
+ { filters.map( ( filter ) => {
+ const filterInView = view.filters.find(
+ ( f ) => f.field === filter.field
+ );
+ const activeElement = filter.elements.find(
+ ( element ) => element.value === filterInView?.value
+ );
+ const activeOperator =
+ filterInView?.operator || filter.operators[ 0 ];
+ return (
+
+ { activeElement &&
+ activeOperator ===
+ OPERATOR_IN &&
+ __( 'Is' ) }
+ { activeElement &&
+ activeOperator ===
+ OPERATOR_NOT_IN &&
+ __( 'Is not' ) }
+ { activeElement && ' ' }
+ { activeElement?.label }
+
+ >
+ }
+ >
+ { filter.name }
+
+ }
>
- { filter.name }
-
- }
- >
- { filter.elements.map( ( element ) => (
- {
- onChangeView( ( currentView ) => ( {
- ...currentView,
- page: 1,
- filters: [
- ...currentView.filters,
- {
- field: filter.field,
- operator: OPERATOR_IN,
- value: element.value,
- },
- ],
- } ) );
- } }
- >
- { element.label }
-
- ) ) }
-
- );
- } ) }
+
+
+ { filter.elements.map( ( element ) => (
+
+ )
+ }
+ onSelect={ ( event ) => {
+ event.preventDefault();
+ onChangeView(
+ ( currentView ) => ( {
+ ...currentView,
+ page: 1,
+ filters: [
+ ...currentView.filters.filter(
+ ( f ) =>
+ f.field !==
+ filter.field
+ ),
+ {
+ field: filter.field,
+ operator:
+ activeOperator,
+ value:
+ activeElement?.value ===
+ element.value
+ ? undefined
+ : element.value,
+ },
+ ],
+ } )
+ );
+ } }
+ >
+ { element.label }
+
+ ) ) }
+
+ { filter.operators.length > 1 && (
+
+ { activeOperator ===
+ OPERATOR_IN &&
+ __( 'Is' ) }
+ { activeOperator ===
+ OPERATOR_NOT_IN &&
+ __( 'Is not' ) }
+ { ' ' }
+ >
+ }
+ >
+ { __( 'Conditions' ) }
+
+ }
+ >
+
+ )
+ }
+ onSelect={ ( event ) => {
+ event.preventDefault();
+ onChangeView(
+ ( currentView ) => ( {
+ ...currentView,
+ page: 1,
+ filters: [
+ ...view.filters.filter(
+ ( f ) =>
+ f.field !==
+ filter.field
+ ),
+ {
+ field: filter.field,
+ operator:
+ OPERATOR_IN,
+ value: filterInView?.value,
+ },
+ ],
+ } )
+ );
+ } }
+ >
+ { __( 'Is' ) }
+
+
+ )
+ }
+ onSelect={ ( event ) => {
+ event.preventDefault();
+ onChangeView(
+ ( currentView ) => ( {
+ ...currentView,
+ page: 1,
+ filters: [
+ ...view.filters.filter(
+ ( f ) =>
+ f.field !==
+ filter.field
+ ),
+ {
+ field: filter.field,
+ operator:
+ OPERATOR_NOT_IN,
+ value: filterInView?.value,
+ },
+ ],
+ } )
+ );
+ } }
+ >
+ { __( 'Is not' ) }
+
+
+ ) }
+ {
+ event.preventDefault();
+ onChangeView( ( currentView ) => ( {
+ ...currentView,
+ page: 1,
+ filters:
+ currentView.filters.filter(
+ ( f ) =>
+ f.field !==
+ filter.field
+ ),
+ } ) );
+ } }
+ >
+ { sprintf(
+ /* translators: 1: Filter name. e.g.: "Reset Author". */
+ __( 'Reset %1$s' ),
+ filter.name.toLowerCase()
+ ) }
+
+
+
+ );
+ } ) }
+
+ {
+ event.preventDefault();
+ onChangeView( ( currentView ) => ( {
+ ...currentView,
+ page: 1,
+ filters: [],
+ } ) );
+ } }
+ >
+ { __( 'Reset filters' ) }
+
+
);
}
diff --git a/packages/dataviews/src/filter-summary.js b/packages/dataviews/src/filter-summary.js
index 3c30c6837103a..fc0f8848f6a93 100644
--- a/packages/dataviews/src/filter-summary.js
+++ b/packages/dataviews/src/filter-summary.js
@@ -13,7 +13,7 @@ import { Children, Fragment } from '@wordpress/element';
/**
* Internal dependencies
*/
-import { OPERATOR_IN, OPERATOR_NOT_IN } from './constants';
+import { OPERATOR_IN, OPERATOR_NOT_IN, LAYOUT_LIST } from './constants';
import { unlock } from './lock-unlock';
const {
@@ -73,6 +73,10 @@ function WithSeparators( { children } ) {
}
export default function FilterSummary( { filter, view, onChangeView } ) {
+ if ( view.type === LAYOUT_LIST ) {
+ return null;
+ }
+
const filterInView = view.filters.find( ( f ) => f.field === filter.field );
const activeElement = filter.elements.find(
( element ) => element.value === filterInView?.value
diff --git a/packages/dataviews/src/filters.js b/packages/dataviews/src/filters.js
index e2d24e7a848ee..153372379cf8d 100644
--- a/packages/dataviews/src/filters.js
+++ b/packages/dataviews/src/filters.js
@@ -46,29 +46,31 @@ export default function Filters( { fields, view, onChangeView } ) {
}
} );
- const filterComponents = filters.map( ( filter ) => {
- if ( ! filter.isVisible ) {
- return null;
- }
-
- return (
-
- );
- } );
-
- filterComponents.push(
+ const addFilter = (
);
+ const filterComponents = [
+ addFilter,
+ ...filters.map( ( filter ) => {
+ if ( ! filter.isVisible ) {
+ return null;
+ }
+
+ return (
+
+ );
+ } ),
+ ];
if ( filterComponents.length > 1 ) {
filterComponents.push(
diff --git a/packages/dataviews/src/reset-filters.js b/packages/dataviews/src/reset-filters.js
index d78c06624087a..503892b6e0737 100644
--- a/packages/dataviews/src/reset-filters.js
+++ b/packages/dataviews/src/reset-filters.js
@@ -4,7 +4,16 @@
import { Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
+/**
+ * Internal dependencies
+ */
+import { LAYOUT_LIST } from './constants';
+
export default ( { view, onChangeView } ) => {
+ if ( view.type === LAYOUT_LIST ) {
+ return null;
+ }
+
return (