Skip to content

Commit

Permalink
DataViews: add AND logic operators to filters (WordPress#59953)
Browse files Browse the repository at this point in the history
Co-authored-by: oandregal <oandregal@git.wordpress.org>
Co-authored-by: jameskoster <jameskoster@git.wordpress.org>
  • Loading branch information
3 people authored and carstingaxion committed Mar 27, 2024
1 parent 8544006 commit a2cec8f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 6 deletions.
1 change: 1 addition & 0 deletions packages/dataviews/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Enhancement

- Two new operators have been added: `isAll` and `isNotAll`. These are meant to represent `AND` operations. For example, `Category is all: Book, Review, Science Fiction` would represent all items that have all three categories selected.
- DataViews now supports multi-selection. A new set of filter operators has been introduced: `is`, `isNot`, `isAny`, `isNone`. Single-selection operators are `is` and `isNot`, and multi-selection operators are `isAny` and `isNone`. If no operators are declared for a filter, it will support multi-selection. Additionally, the old filter operators `in` and `notIn` operators have been deprecated and will work as `is` and `isNot` respectively. Please, migrate to the new operators as they'll be removed soon.

## 0.7.0 (2024-03-06)
Expand Down
16 changes: 10 additions & 6 deletions packages/dataviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,12 +305,16 @@ Callback that signals the user triggered the details for one of more items, and

Allowed operators for fields of type `enumeration`:

- `is`: whether the item is equal to a single value.
- `isNot`: whether the item is not equal to a single value.
- `isAny`: whether the item is present in a list of values.
- `isNone`: whether the item is not present in a list of values.

`is` and `isNot` are single-selection operators, while `isAny` and `isNone` are multi-selection. By default, a filter with no operators declared will support multi-selection. A filter cannot mix single-selection & multi-selection operators; if a single-selection operator is present in the list of valid operators, the multi-selection ones will be discarded and the filter won't allow selecting more than one item.
| Operator | Selection | Description | Example |
| --- | --- | --- | --- |
| `is` | Single item | `EQUAL TO`. The item's field is equal to a single value. | Author is Admin |
| `isNot` | Single item | `NOT EQUAL TO`. The item's field is not equal to a single value. | Author is not Admin |
| `isAny` | Multiple items | `OR`. The item's field is present in a list of values. | Author is any: Admin, Editor |
| `isNone` | Multiple items | `NOT OR`. The item's field is not present in a list of values. | Author is none: Admin, Editor |
| `isAll` | Multiple items | `AND`. The item's field has all of the values in the list. | Category is all: Book, Review, Science Fiction |
| `isNotAll` | Multiple items | `NOT AND`. The item's field doesn't have all of the values in the list. | Category is not all: Book, Review, Science Fiction |

`is` and `isNot` are single-selection operators, while `isAny`, `isNone`, `isAll`, and `isNotALl` are multi-selection. By default, a filter with no operators declared will support the `isAny` and `isNone` multi-selection operators. A filter cannot mix single-selection & multi-selection operators; if a single-selection operator is present in the list of valid operators, the multi-selection ones will be discarded and the filter won't allow selecting more than one item.

> The legacy operators `in` and `notIn` have been deprecated and will be removed soon. In the meantime, they work as `is` and `isNot` operators, respectively.
Expand Down
13 changes: 13 additions & 0 deletions packages/dataviews/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ export const OPERATOR_IS = 'is';
export const OPERATOR_IS_NOT = 'isNot';
export const OPERATOR_IS_ANY = 'isAny';
export const OPERATOR_IS_NONE = 'isNone';
export const OPERATOR_IS_ALL = 'isAll';
export const OPERATOR_IS_NOT_ALL = 'isNotAll';

export const ALL_OPERATORS = [
OPERATOR_IS,
OPERATOR_IS_NOT,
OPERATOR_IS_ANY,
OPERATOR_IS_NONE,
OPERATOR_IS_ALL,
OPERATOR_IS_NOT_ALL,
];
export const OPERATORS = {
[ OPERATOR_IS ]: {
Expand All @@ -47,6 +52,14 @@ export const OPERATORS = {
key: 'is-none-filter',
label: __( 'Is none' ),
},
[ OPERATOR_IS_ALL ]: {
key: 'is-all-filter',
label: __( 'Is all' ),
},
[ OPERATOR_IS_NOT_ALL ]: {
key: 'is-not-all-filter',
label: __( 'Is not all' ),
},
};

// Sorting
Expand Down
26 changes: 26 additions & 0 deletions packages/dataviews/src/filter-summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import {
OPERATOR_IS_NOT,
OPERATOR_IS_ANY,
OPERATOR_IS_NONE,
OPERATOR_IS_ALL,
OPERATOR_IS_NOT_ALL,
} from './constants';

const FilterText = ( { activeElements, filterInView, filter } ) => {
Expand Down Expand Up @@ -66,6 +68,30 @@ const FilterText = ( { activeElements, filterInView, filter } ) => {
);
}

if ( filterInView?.operator === OPERATOR_IS_ALL ) {
return createInterpolateElement(
sprintf(
/* translators: 1: Filter name. 3: Filter value. e.g.: "Author is all: Admin, Editor". */
__( '<Name>%1$s is all: </Name><Value>%2$s</Value>' ),
filter.name,
activeElements.map( ( element ) => element.label ).join( ', ' )
),
filterTextWrappers
);
}

if ( filterInView?.operator === OPERATOR_IS_NOT_ALL ) {
return createInterpolateElement(
sprintf(
/* translators: 1: Filter name. 3: Filter value. e.g.: "Author is not all: Admin, Editor". */
__( '<Name>%1$s is not all: </Name><Value>%2$s</Value>' ),
filter.name,
activeElements.map( ( element ) => element.label ).join( ', ' )
),
filterTextWrappers
);
}

if ( filterInView?.operator === OPERATOR_IS ) {
return createInterpolateElement(
sprintf(
Expand Down

0 comments on commit a2cec8f

Please sign in to comment.