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 (