This commit is contained in:
Stephen Boettcher 2026-05-04 05:18:57 +02:00 committed by GitHub
commit fdf5241630
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 55 additions and 8 deletions

View file

@ -3,6 +3,7 @@ import React, { Component } from 'react';
import SelectInput from 'Components/Form/SelectInput';
import IconButton from 'Components/Link/IconButton';
import { filterBuilderTypes, filterBuilderValueTypes, icons } from 'Helpers/Props';
import * as filterTypes from 'Helpers/Props/filterTypes';
import sortByProp from 'Utilities/Array/sortByProp';
import BoolFilterBuilderRowValue from './BoolFilterBuilderRowValue';
import DateFilterBuilderRowValue from './DateFilterBuilderRowValue';
@ -226,6 +227,13 @@ class FilterBuilderRow extends Component {
const selectedFilterBuilderProp = this.selectedFilterBuilderProp;
const operatorsWithoutValue = [
filterTypes.IS_EMPTY,
filterTypes.IS_NOT_EMPTY
];
const requiresValue = !operatorsWithoutValue.includes(filterType);
const keyOptions = filterBuilderProps.map((availablePropFilter) => {
const { name, label } = availablePropFilter;
@ -262,10 +270,11 @@ class FilterBuilderRow extends Component {
/>
}
</div>
<div className={styles.valueInputContainer}>
{
filterValue != null && !!selectedFilterBuilderProp &&
{
requiresValue &&
filterValue != null &&
!!selectedFilterBuilderProp &&
<div className={styles.valueInputContainer}>
<ValueComponent
filterType={filterType}
filterValue={filterValue}
@ -273,8 +282,8 @@ class FilterBuilderRow extends Component {
sectionItems={sectionItems}
onChange={this.onFilterChange}
/>
}
</div>
</div>
}
<div className={styles.actionsContainer}>
<IconButton

View file

@ -28,6 +28,14 @@ export const possibleFilterTypes = {
{
key: filterTypes.NOT_CONTAINS,
value: () => translate('FilterDoesNotContain')
},
{
key: filterTypes.IS_EMPTY,
value: () => translate('FilterIsEmpty')
},
{
key: filterTypes.IS_NOT_EMPTY,
value: () => translate('FilterIsNotEmpty')
}
],

View file

@ -55,6 +55,30 @@ const filterTypePredicates = {
[filterTypes.NOT_ENDS_WITH]: function(itemValue, filterValue) {
return !itemValue.toLowerCase().endsWith(filterValue.toLowerCase());
},
[filterTypes.IS_EMPTY]: function(itemValue, filterValue) {
if (itemValue === null || itemValue === undefined) {
return true;
}
if (Array.isArray(itemValue) || typeof itemValue === 'string') {
return itemValue.length === 0;
}
return false;
},
[filterTypes.IS_NOT_EMPTY]: function(itemValue, filterValue) {
if (itemValue === null || itemValue === undefined) {
return false;
}
if (Array.isArray(itemValue) || typeof itemValue === 'string') {
return itemValue.length > 0;
}
return true;
}
};

View file

@ -14,6 +14,8 @@ export const STARTS_WITH = 'startsWith';
export const NOT_STARTS_WITH = 'notStartsWith';
export const ENDS_WITH = 'endsWith';
export const NOT_ENDS_WITH = 'notEndsWith';
export const IS_EMPTY = 'isEmpty';
export const IS_NOT_EMPTY = 'isNotEmpty';
export const all = [
CONTAINS,
@ -31,5 +33,7 @@ export const all = [
STARTS_WITH,
NOT_STARTS_WITH,
ENDS_WITH,
NOT_ENDS_WITH
NOT_ENDS_WITH,
IS_EMPTY,
IS_NOT_EMPTY
];

View file

@ -43,7 +43,7 @@ function filter(items, state) {
if (filterPredicates && filterPredicates.hasOwnProperty(key)) {
const predicate = filterPredicates[key];
if (Array.isArray(value)) {
if (Array.isArray(value) && value.length > 0) {
if (
type === filterTypes.NOT_CONTAINS ||
type === filterTypes.NOT_EQUAL

View file

@ -697,6 +697,8 @@
"FilterNotInLast": "not in the last",
"FilterNotInNext": "not in the next",
"FilterStartsWith": "starts with",
"FilterIsEmpty": "is empty",
"FilterIsNotEmpty": "is NOT empty",
"Filters": "Filters",
"FilterMoviePropertiesOnlyNotFileWarning": "Filters are available only for the properties of a movie, they are not available for properties of the file(s) you may have for that movie.",
"FirstDayOfWeek": "First Day of Week",